Android runtime (ART) включает в себя компилятор just-in-time (JIT) с профилированием кода, который постоянно улучшает производительность приложений Android по мере их выполнения. Компилятор JIT дополняет текущий компилятор ahead-of-time (AOT) ART и улучшает производительность времени выполнения, экономит место на диске и ускоряет обновления приложений и системы. Он также улучшает компилятор AOT, избегая замедления системы во время автоматических обновлений приложений или перекомпиляции приложений во время обновлений по воздуху (OTA).
Хотя JIT и AOT используют один и тот же компилятор с похожим набором оптимизаций, сгенерированный код может быть не идентичным. JIT использует информацию о типе времени выполнения, может лучше встраиваться и делает возможной компиляцию с заменой на стеке (OSR), все это генерирует немного другой код.
JIT-архитектура
JIT-компиляция
Составление JIT включает в себя следующие виды деятельности:
- Пользователь запускает приложение, которое затем активирует ART для загрузки файла
.dex
.- Если файл
.oat
(бинарный файл AOT для файла.dex
) доступен, ART использует его напрямую. Хотя файлы.oat
генерируются регулярно, они не всегда содержат скомпилированный код (бинарный файл AOT). - Если файл
.oat
не содержит скомпилированного кода, ART запускает JIT и интерпретатор для выполнения файла.dex
.
- Если файл
- JIT включен для любого приложения, которое не скомпилировано в соответствии с фильтром
speed
компиляции (который гласит «скомпилируйте как можно больше из приложения»). - Данные профиля JIT сохраняются в файле в системном каталоге, доступ к которому имеет только приложение.
- Демон компиляции AOT (
dex2oat
) анализирует этот файл для управления своей компиляцией.Рисунок 3. Действия демона JIT.
Сервис Google Play является примером, используемым другими приложениями, которые ведут себя аналогично общим библиотекам.
Рабочий процесс JIT
- Информация профилирования хранится в кэше кода и подвергается сборке мусора при нехватке памяти.
- Нет никакой гарантии, что снимок, сделанный, когда приложение работало в фоновом режиме, будет содержать полные данные (т. е. все, что было обработано JIT).
- Не предпринимается никаких попыток гарантировать, что все записано (поскольку это может повлиять на производительность выполнения).
- Методы могут находиться в трех различных состояниях:
- интерпретируется (код dex)
- 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
Примечание: эта команда сохраняет данные локального профиля.