Настройка ART

На этой странице обсуждается, как настроить ART и его параметры компиляции. Рассматриваемые здесь темы включают настройку предварительной компиляции образа системы, параметры компиляции dex2oat и то, как найти компромисс между пространством системного раздела, пространством раздела данных и производительностью.

См АРТ и Dalvik , в формат Dalvik Executable , а остальные страницы source.android.com к работе с АРТ. См контролирующей App Поведение на Android Runtime (ART) , чтобы убедиться , что ваши приложения работают должным образом.

Как работает АРТ

ART использует предварительную компиляцию (AOT) и, начиная с Android 7.0 (Nougat или N), использует гибридную комбинацию AOT, JIT-компиляции и компиляции на основе профиля. Комбинация всех этих режимов компиляции настраивается и будет обсуждаться в этом разделе. Например, устройства Pixel настроены со следующим потоком компиляции:

  1. Приложение изначально устанавливается без компиляции AOT. Первые несколько запусков приложения оно будет интерпретировано, а часто выполняемые методы будут JIT-компиляцией.
  2. Когда устройство бездействует и заряжается, демон компиляции запускается для AOT-компиляции часто используемого кода на основе профиля, созданного во время первых запусков.
  3. При следующем перезапуске приложения будет использоваться код, управляемый профилем, и не будет выполняться JIT-компиляция во время выполнения для уже скомпилированных методов. Методы, которые получают JIT-компиляцию во время новых запусков, будут добавлены в профиль, который затем будет выбран демоном компиляции.

АРТ содержит компилятор (The dex2oat инструмента) и среды выполнения ( libart.so ) , который загружается для запуска зиготы. dex2oat инструмент берет файл APK и генерирует один или несколько артефактов компиляции файлов , что во время выполнения нагрузок. Количество файлов, их расширения и имена могут изменяться в зависимости от выпуска, но начиная с выпуска Android O создаются следующие файлы:

  • .vdex : содержит несжатый DEX код APK, с некоторыми дополнительными метаданными для ускорения проверки.
  • .odex : содержит АОТ скомпилированного кода для методов в АПК.
  • .art (optional) по .art (optional) : содержит АРТ внутренних представления некоторых строк и классов , перечисленных в APK, используемых для запуска приложения скорости.

Варианты компиляции

Варианты составления АРТ делятся на две категории:

  1. Конфигурация системного ПЗУ: какой код компилируется AOT при построении образа системы.
  2. Конфигурация времени выполнения: как ART компилирует и запускает приложения на устройстве.

Один основной параметр ART для настройки этих двух категорий является компилятор фильтров. Компилятор фильтры диск как ART компилирует DEX код и вариант передается dex2oat инструмента. Начиная с Android O, официально поддерживаются четыре фильтра:

  • проверить: только запустить код проверки DEX.
  • животвори: запустить код проверки DEX и оптимизировать некоторые инструкции DEX , чтобы получить более высокую производительность интерпретатора.
  • скорость: Код подтверждения запуска DEX и АОТ-компиляции все методы.
  • скоростно-профиля: Код подтверждения запуска DEX и методы АОТ-компиляции , перечисленные в файле профиля.

Конфигурация системного ПЗУ

Для настройки системного ПЗУ доступен ряд вариантов сборки ART. Как настроить эти параметры в зависимости от доступного пространства для хранения /system и количества предустановленных приложений. Файлы JAR / APK, которые скомпилированы в системное ПЗУ, можно разделить на четыре категории:

  • Загрузочный код классов: скомпилировано с фильтром скорости компилятора по умолчанию.
  • Код сервера системы: скомпилирован с фильтром скорости компилятором по умолчанию.
  • Конкретного продукт основных приложений: скомпилированы с фильтром скорости компилятора по умолчанию.
  • Все остальные приложения: скомпилированные с Quicken фильтром компилятора по умолчанию.

Параметры Makefile

  • WITH_DEXPREOPT
  • Если dex2oat вызывается DEX кода , установленного на системе изображения. Включено по умолчанию.

  • DONT_DEXPREOPT_PREBUILTS (с Android L)
  • Включение DONT_DEXPREOPT_PREBUILTS предотвращающих в prebuilts от того предварительно оптимизировано. Эти приложения , которые имеют include $(BUILD_PREBUILT) , указанный в их Android.mk , таких как Gmail. Пропуск предварительной оптимизации скомпилированных приложений, которые могут быть обновлено через Google Play экономит /system пространства , но делает надстройку в первый раз загрузки.

  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER (с Android 9)
  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER определяет фильтр компилятора по умолчанию для предварительно оптимизированных приложений. Эти приложения , которые имеют include $(BUILD_PREBUILT) , указанный в их Android.mk , таких как Gmail. Если не указано, значение по умолчанию - quicken.

  • WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY (новый в Android O MR1)
  • Включение WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY предварительно оптимизирует только загрузочный путь к классам и система сервера банки.

  • LOCAL_DEX_PREOPT
  • Предварительная оптимизация также может быть включена или отключена на индивидуальной основе приложения, указав LOCAL_DEX_PREOPT параметра в определении модуля. Это может быть полезно для отключения предварительной оптимизации приложений, которые могут немедленно получать обновления Google Play, поскольку обновления сделают предварительно оптимизированный код в образе системы устаревшим. Это также полезно для экономии места при обновлении основной версии OTA, поскольку пользователи могут уже иметь более новые версии приложений в разделе данных.

    LOCAL_DEX_PREOPT поддерживает значения «истинный» или «ложь» , чтобы включить или отключить предварительную оптимизацию, соответственно. Кроме того, «nostripping» может быть , если предварительно оптимизация не должна обнажать classes.dex файл из APK или файла JAR. Обычно этот файл удаляется, поскольку он больше не нужен после предварительной оптимизации, но этот последний параметр необходим, чтобы подписи сторонних APK оставались действительными.

  • PRODUCT_DEX_PREOPT_BOOT_FLAGS
  • Передает варианты dex2oat для управления , как составлен загрузочный образ. Его можно использовать для указания настраиваемых списков классов изображений, списков скомпилированных классов и фильтров компилятора.

  • PRODUCT_DEX_PREOPT_DEFAULT_FLAGS
  • Передает опции для dex2oat к контролю , как все , кроме загрузочного образа компилируется.

  • PRODUCT_DEX_PREOPT_MODULE_CONFIGS
  • Обеспечивает возможность передачи dex2oat опций для конкретного модуля и конфигурации продукта. Он установлен в продукте в device.mk файл по $(call add-product-dex-preopt-module-config,<modules>,<option>) , где <modules> список LOCAL_MODULE и LOCAL_PACKAGE имен для JAR и APK файлы соответственно.

  • PRODUCT_DEXPREOPT_SPEED_APPS (New in Android O)
  • Список приложений , которые были определены в качестве основных для продуктов и которые желательно скомпилировать с фильтром скорости компиляции. Например, постоянные приложения, такие как SystemUI, получают возможность использовать компиляцию на основе профиля только при следующей перезагрузке, поэтому для продукта может быть лучше, чтобы эти приложения всегда компилировались AOT.

  • PRODUCT_SYSTEM_SERVER_APPS (New in Android O)
  • Список приложений, загружаемых системным сервером. Эти приложения будут скомпилированы по умолчанию с фильтром скорость компиляции.

  • PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD(Post Android O)
  • Следует ли включать на устройство отладочную версию ART. По умолчанию это включено для сборок userdebug и eng. Поведение может быть переопределены явно установив опцию истинным или ложным.

    По умолчанию, устройство будет использовать версию неотладочного (libart.so). Для того, чтобы переключатель, установите системное свойство persist.sys.dalvik.vm.lib.2 в libartd.so.

  • WITH_DEXPREOPT_PIC (Removed in Android O)
  • В Android 5.1.0 через Android 6.0.1, WITH_DEXPREOPT_PIC может быть определен для включения позиционно-независимого кода (PIC). При этом скомпилированный код из образа не нужно перемещать из / system в / data / dalvik-cache, что экономит место в разделе данных. Однако это незначительно влияет на время выполнения, поскольку отключает оптимизацию, использующую позиционно-зависимый код. Как правило, устройства, желающие сэкономить место в / data, должны включать компиляцию PIC.

    В Android 7.0 компиляция PIC была включена по умолчанию.

  • WITH_DEXPREOPT_BOOT_IMG_ONLY (удален в Android O MR1)
  • Этот параметр был заменен на WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY, который также преопределяет jar-файлы системного сервера.

Конфигурация пути к классам загрузки

  • Список предварительно загруженных классов
  • Список предварительно загруженных классов - это список классов, которые зигота инициализирует при запуске. Это избавляет каждое приложение от необходимости запускать эти инициализаторы классов по отдельности, позволяя им запускаться быстрее и совместно использовать страницы в памяти. Предустановленный список файлы классов находятся на frameworks/base/config/preloaded-classes по умолчанию, и он содержит список , который настроенный для обычного использования телефона. Это может быть другим для других устройств, например носимых, и должно быть соответствующим образом настроено. Будьте осторожны при настройке; добавление слишком большого количества классов тратит память при загрузке неиспользуемых классов. Добавление слишком небольшого количества классов вынуждает каждое приложение иметь свою собственную копию, что, опять же, расходует память.

    Пример использования (в файле device.mk):

    PRODUCT_COPY_FILES += <filename>:system/etc/preloaded-classes
    

    Примечание: Эта строка должна быть перед наследованием любых конфигурации продукта мейкфайлов , которые получают один по умолчанию из: build/target/product/base.mk

  • Список классов изображений
  • Список классов изображений - это список классов, которые dex2oat инициализирует заранее и сохраняет в файле boot.art. Это позволяет зиготе загружать эти результаты из файла boot.art при запуске вместо запуска инициализаторов этих классов во время предварительной загрузки. Ключевой особенностью этого является то, что страницы, загруженные из образа и совместно используемые процессами, могут быть чистыми, что позволяет легко выгружать их в ситуациях нехватки памяти. В L по умолчанию список классов изображений использует тот же список, что и список предварительно загруженных классов. Начиная с post-L в AOSP, список пользовательских классов изображений можно указать с помощью:

    PRODUCT_DEX_PREOPT_BOOT_FLAGS
    

    Пример использование (в продукте device.mk ):

    PRODUCT_DEX_PREOPT_BOOT_FLAGS += --image-classes=<filename>
    
  • Скомпилированный список классов
  • В post-L AOSP можно указать подмножество классов из пути к классам загрузки для компиляции во время предварительной оптимизации с использованием списка скомпилированных классов. Это может быть полезным вариантом для устройств, которые очень ограничены в пространстве и не могут вместить весь предварительно оптимизированный загрузочный образ. Однако классы заметок, не указанные в этом списке, не будут компилироваться - даже на устройстве - и должны интерпретироваться, что может повлиять на производительность во время выполнения. По умолчанию dex2oat будет искать список скомпилированных классов в $ OUT / system / etc / compiled-classes, так что пользовательский может быть скопирован в это место с помощью device.mk. Особое расположение файла также может быть указан с помощью:

    PRODUCT_DEX_PREOPT_BOOT_FLAGS
    

    Пример использование (в продукте device.mk ):

    PRODUCT_COPY_FILES += <filename>:system/etc/compiled-classes
    

    Примечание: Эта строка должна быть перед наследованием любых конфигурации продукта мейкфайлов , которые получают один по умолчанию из: build/target/product/base.mk

Конфигурация времени выполнения

Варианты Jit

Следующие параметры влияют на выпуски Android только там, где доступен компилятор ART JIT.

  • dalvik.vm.usejit: включена ли JIT.
  • dalvik.vm.jitinitialsize (по умолчанию 64 КБ): начальная емкость кеша кода. Кеш кода будет регулярно собирать мусор и при необходимости увеличиваться.
  • dalvik.vm.jitmaxsize (по умолчанию 64M): максимальная емкость кеша кода.
  • dalvik.vm.jitthreshold: (по умолчанию 10000) - это порог, который должен пройти счетчик «горячего» метода, чтобы метод был JIT-компилирован. Счетчик «горячего состояния» - это показатель внутренней среды выполнения. Он включает в себя количество звонков, обратных переходов и другие факторы.
  • dalvik.vm.usejitprofiles: включены ли профили JIT; это можно использовать, даже если dalvik.vm.usejit ложно. Обратите внимание , что , если это неверно, компилятор фильтр скорости профиль не АОТ-компиляции любого метода и эквивалентно ускоряться.
  • dalvik.vm.jitprithreadweight (по умолчанию dalvik.vm.jitthreshold / 20) - Вес «образцов» JIT (см. jitthreshold) для потока пользовательского интерфейса приложения. Используется для ускорения компиляции методов, которые напрямую влияют на взаимодействие пользователей с приложением.
  • dalvik.vm.jittransitionweight: (по умолчанию dalvik.vm.jitthreshold / 10) вес вызова метода, который переходит между кодом компиляции и интерпретатором. Это помогает убедиться, что задействованные методы скомпилированы для минимизации переходов (что дорого).

Параметры диспетчера пакетов

Начиная с Android 7.0, существует общий способ указать уровень компиляции / проверки, который происходил на разных этапах. Уровни компиляции можно настроить с помощью системных свойств, по умолчанию:

  • pm.dexopt.install=speed-profile
  • Это фильтр компиляции, используемый при установке приложений через Google Play. Мы рекомендуем установить фильтр установки на профиль скорости, чтобы разрешить использование профилей из файлов метаданных dex. Обратите внимание: если профиль не указан или он пуст, профиль скорости эквивалентен quicken.

  • pm.dexopt.bg-dexopt=speed-profile
  • Это фильтр компиляции, используемый, когда устройство находится в режиме ожидания, заряжается и полностью заряжено. Попробуйте фильтр компилятора скорости профиль , чтобы воспользоваться профилем наведением компиляции и сэкономить на хранении.

  • pm.dexopt.boot=verify
  • Фильтр компиляции, используемый после обновления по беспроводной сети. Мы настоятельно рекомендуем проверить компилятор фильтра для этого параметра , чтобы избежать очень длительного времени загрузки.

  • pm.dexopt.first-boot=quicken
  • Фильтр компиляции при первой загрузке устройства. Используемый здесь фильтр влияет только на время загрузки после заводской установки. Мы рекомендуем фильтр Quicken для того , чтобы избежать длительного времени , прежде чем пользователь получает использовать телефон в первый раз. Обратите внимание , что если все приложения в /system уже скомпилированы с Quicken фильтром компилятора или скомпилированы с фильтром скорости или скорость профиля компилятора, pm.dexopt.first-boot не имеет никакого эффекта.

Параметры Dex2oat

Обратите внимание , что эти параметры влияют на dex2oat во время на устройстве компиляции, а также во время предварительной оптимизации, в то время как большинство вариантов обсуждалось выше влияет только предварительно оптимизация.

Для управления dex2oat в то время как она компилируется загрузочным образом:

  • dalvik.vm.image-dex2oat-Xms: начальный размер кучи
  • dalvik.vm.image-dex2oat-Xmx: максимальный размер кучи
  • dalvik.vm.image-dex2oat-filter: параметр фильтра компилятора
  • dalvik.vm.image-dex2oat-thread: количество используемых потоков

Для управления dex2oat пока она компилируется все , кроме загрузочного образа:

  • dalvik.vm.dex2oat-Xms: начальный размер кучи
  • dalvik.vm.dex2oat-Xmx: максимальный размер кучи
  • dalvik.vm.dex2oat-filter: параметр фильтра компилятора

В выпусках до Android 6.0 предусмотрена одна дополнительная опция для компиляции всего, кроме загрузочного образа:

  • dalvik.vm.dex2oat-thread: количество используемых потоков

Начиная с Android 6.1, это становится двумя дополнительными опциями для компиляции всего, кроме загрузочного образа:

  • dalvik.vm.boot-dex2oat-thread: количество потоков, используемых во время загрузки
  • dalvik.vm.dex2oat-thread: количество потоков, используемых после загрузки

Начиная с Android 7.1, доступны два варианта управления использованием памяти при компиляции всего, кроме загрузочного образа:

  • dalvik.vm.dex2oat-very-large: минимальный общий размер файла dex в байтах для отключения компиляции AOT
  • dalvik.vm.dex2oat-swap: использовать файл подкачки dex2oat (для устройств с низким объемом памяти)

Параметры , которые контролируют начальный и максимальный размер кучи для dex2oat не должны быть уменьшены , так как они могут ограничить , какие приложения может быть скомпилированы.

Начиная с Android 11, доступны три параметра привязки ЦП, позволяющие ограничивать потоки компилятора определенной группой ЦП:

  • dalvik.vm.boot-dex2oat-cpu-set: процессоры, выполняющие потоки dex2oat во время загрузки
  • dalvik.vm.image-dex2oat-cpu-set: процессоры, работающие под dex2oat при компиляции загрузочного образа
  • dalvik.vm.dex2oat-cpu-set: процессоры, выполняющие потоки dex2oat после загрузки

ЦП следует указывать в виде списка идентификаторов ЦП, разделенных запятыми. Например, чтобы запустить dex2oat на процессорах 0-3, установите:

dalvik.vm.dex2oat-cpu-set=0,1,2,3

При настройке свойств сродства ЦП мы рекомендуем сопоставить соответствующее свойство для количества потоков dex2oat, чтобы оно соответствовало количеству выбранных ЦП, чтобы избежать ненужной памяти и конфликтов ввода-вывода:

dalvik.vm.dex2oat-cpu-set=0,1,2,3
dalvik.vm.dex2oat-threads=4

Начиная с Android 12 были добавлены следующие опции:

  • dalvik.vm.ps-min-first-save-ms: время ожидания, пока среда выполнения сгенерирует профиль приложения, при первом запуске приложения
  • dalvik.vm.ps-min-save-period-ms: минимальное время ожидания перед обновлением профиля приложения.
  • dalvik.vm.systemservercompilerfilter: фильтр компилятора, который устройство будет использовать при перекомпиляции системного сервера

Специальная конфигурация A / B

Конфигурация ПЗУ

Начиная с Android 7.0, устройства могут использовать два системные разделы для включения обновлений системы A / B . Чтобы сэкономить на размере системного раздела, предварительно настроенные файлы можно установить в неиспользуемый второй системный раздел. Затем они копируются в раздел данных при первой загрузке.

Пример использования (в device-common.mk ):

PRODUCT_PACKAGES += \
     cppreopts.sh
PRODUCT_PROPERTY_OVERRIDES += \
     ro.cp_system_other_odex=1

А в устройстве это BoardConfig.mk :

BOARD_USES_SYSTEM_OTHER_ODEX := true

Обратите внимание, что код пути к классам загрузки, код системного сервера и базовые приложения для конкретных продуктов всегда компилируются в системный раздел. По умолчанию все остальные приложения компилируются в неиспользуемый второй системный раздел. Это можно управлять с помощью SYSTEM_OTHER_ODEX_FILTER , который имеет значение по умолчанию:

SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%

Фон dexopt OTA

С устройствами с поддержкой A / B приложения могут компилироваться в фоновом режиме для обновления до нового образа системы. См App компиляции в фоновом режиме , чтобы при необходимости включить сценарий компиляции и бинарные файлы в системе изображения. Фильтр компиляции, используемый для этой компиляции, контролируется с помощью:

pm.dexopt.ab-ota=speed-profile

Мы рекомендуем использовать скоростной профиль , чтобы воспользоваться профилем руководствовался компиляция и сэкономить на хранении.