Внедрить 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 

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