Среда выполнения Android (ART) включает JIT-компилятор с профилированием кода, который постоянно повышает производительность приложений Android по мере их выполнения. Компилятор JIT дополняет текущий компилятор ART с опережением времени (AOT) и повышает производительность во время выполнения, экономит место на диске и ускоряет обновление приложений и системы. Он также улучшает компилятор 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
Очистка данных профиля
Чтобы очистить данные профиля и удалить скомпилированный код, выполните следующее:
- Для одного пакета:
adb shell cmd package compile --reset my-package
- Для всех пакетов:
adb shell cmd package compile --reset -a