Внедрить JIT-компилятор ART

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

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

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

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

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

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

Профильная подборка
Рисунок 2. Компиляция на основе профиля.
  1. Пользователь запускает приложение, которое затем запускает ART для загрузки файла .dex .
    • Если файл .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
    

Очистить данные профиля

На Android 13 или более ранней версии

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

adb shell pm compile --reset 

На Android 14 или более поздней версии

Чтобы очистить только данные локального профиля:

adb shell pm art clear-app-profiles 

Примечание. В отличие от команды для Android 13 или более ранней версии, эта команда не удаляет данные внешнего профиля (.dm), установленные вместе с приложением.

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

adb shell pm compile --reset 

Примечание. Эта команда не удаляет скомпилированный код, созданный на основе данных внешнего профиля (`.dm`), установленных вместе с приложением.

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

adb shell cmd package compile -m verify -f 

Примечание. Эта команда сохраняет данные локального профиля.