Внедрить 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-архитектура
Рисунок 4. Схема потока данных «точно в срок» (JIT).
  • Информация, полученная в результате профилирования, хранится в кэше кода и подвергается сборке мусора при нехватке памяти.
    • Нет никакой гарантии, что снимок, сделанный во время работы приложения в фоновом режиме, будет содержать полные данные (т.е. все, что было скомпилировано JIT-компилятором).
    • Не предпринимается попыток обеспечить запись всех данных (поскольку это может повлиять на производительность во время выполнения).
  • Методы могут находиться в трех различных состояниях:
    • интерпретированный (код декса)
    • 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 

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