Реализация компилятора ART Just-In-Time (JIT)

Среда выполнения Android (ART) включает JIT-компилятор с профилированием кода, который постоянно улучшает производительность приложений Android по мере их выполнения. Компилятор JIT дополняет текущий опережающий компилятор (AOT) ART и улучшает производительность во время выполнения, экономит место для хранения и ускоряет обновление приложений и системы. Он также улучшает компилятор AOT, избегая замедления работы системы во время автоматического обновления приложений или перекомпиляции приложений во время обновлений по беспроводной сети (OTA).

Хотя JIT и AOT используют один и тот же компилятор с аналогичным набором оптимизаций, сгенерированный код может не совпадать. JIT использует информацию о типах среды выполнения, может лучше выполнять встраивание и делает возможной компиляцию с заменой стека (OSR), все из которых генерирует немного другой код.

JIT архитектура

JIT архитектура
Рисунок 1. JIT-архитектура.

JIT-компиляция

JIT-компиляция включает в себя следующие действия:

Композиция по профилю
Рисунок 2. Компиляция по профилю.
  1. Пользователь запускает приложение, которое затем запускает ART для загрузки файла .dex .
    • Если файл .oat ( .oat файл AOT для файла .dex ) доступен, ART использует его напрямую. Хотя файлы .oat генерируются регулярно, они не всегда содержат скомпилированный код (двоичный код AOT).
    • Если файл .oat не содержит скомпилированного кода, ART запускается через JIT и интерпретатор для выполнения файла .dex .
  2. JIT включен для любого приложения, которое не скомпилировано в соответствии с фильтром компиляции speed (который говорит «компилируйте столько, сколько вы можете из приложения»).
  3. Данные профиля JIT выгружаются в файл в системном каталоге, доступ к которому имеет только приложение.
  4. Демон компиляции AOT ( dex2oat ) анализирует этот файл для его компиляции.

    Демон JIT
    Рисунок 3. Действия демона JIT.

Сервис Google Play - это пример, используемый другими приложениями, которые ведут себя аналогично разделяемым библиотекам.

Рабочий процесс JIT

JIT архитектура
Рисунок 4. Поток данных JIT.
  • Информация профилирования хранится в кэше кода и подвергается сборке мусора под давлением памяти.
    • Нет гарантии, что моментальный снимок, сделанный, когда приложение работало в фоновом режиме, будет содержать полные данные (т. Е. Все, что было выполнено JIT).
    • Нет попытки гарантировать, что все записано (так как это может повлиять на производительность во время выполнения).
  • Методы могут находиться в трех разных состояниях:
    • интерпретируемый (код dex)
    • JIT скомпилирован
    • AOT скомпилирован
    Если существует как JIT-код, так и AOT-код (например, из-за повторяющейся деоптимизации), JIT-код является предпочтительным.
  • Требования к памяти для запуска JIT без снижения производительности приложения переднего плана зависят от рассматриваемого приложения. Для больших приложений требуется больше памяти, чем для небольших. В целом, большие приложения стабилизируют около 4 МБ.

Включение ведения журнала JIT

Чтобы включить ведение журнала JIT, выполните следующие команды:

adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start

Отключение JIT

Чтобы отключить JIT, выполните следующие команды:

adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start

Принудительная компиляция

Чтобы принудительно выполнить компиляцию, запустите следующее:

adb shell cmd package compile

Общие варианты использования для принудительной компиляции определенного пакета:

  • На основе профиля:
    adb shell cmd package compile -m speed-profile -f my-package
    
  • Полный:
    adb shell cmd package compile -m speed -f my-package
    

Общие варианты использования принудительной компиляции всех пакетов:

  • По профилю:
    adb shell cmd package compile -m speed-profile -f -a
    
  • Полный:
    adb shell cmd package compile -m speed -f -a
    

Очистка данных профиля

Чтобы очистить данные профиля и удалить скомпилированный код, выполните следующее:

  • За одну посылку:
    adb shell cmd package compile --reset my-package
    
  • Для всех пакетов:
    adb shell cmd package compile --reset -a