Профили загрузочных образов

В Android 11 и более поздних версиях поддерживается создание профилей загрузочных образов, в которых содержится информация о коде различных компонентов системного уровня, таких как системный сервер и загрузочный путь к классам. Среда выполнения Android (ART) использует эту информацию для оптимизации системы. Некоторые из этих оптимизаций критически важны для производительности Android и влияют на выполнение всего ненативного кода (на уровне системы или приложения). В некоторых случаях профили загрузочных образов могут влиять на производительность выполнения и потребление памяти на двузначные проценты.

Как получить информацию о профиле загрузки

Профили загрузочных образов создаются на основе профилей приложений, которые выполняются во время критических путей пользователя. В определенной конфигурации устройства ART захватывает (как часть профилей JIT) методы и классы загрузочного пути, используемые приложениями, а затем записывает эту информацию в профиль приложения (например, /data/misc/profiles/cur/0/com.android.chrome/primary.prof), где она индексируется по загрузочному пути исполняемого файла Dalvik (DEX) (см. формат профиля ART).

Проверьте профили приложений, записанные во время CUJ, чтобы определить, какая часть пути к классам загрузки используется чаще всего и наиболее важна для оптимизации (например, см. Формат профиля ART). Включение всех методов или классов негативно влияет на производительность, поэтому сосредоточьтесь на наиболее часто используемых путях выполнения кода. Например, если метод из пути к классам загрузки используется одним приложением, он не должен быть частью профилей загрузки. Для каждого устройства нужно настроить выбор метода или класса в зависимости от выбранного сценария использования и объема данных, полученных в ходе тестирования.

Чтобы объединить информацию о пути к классам загрузки из всех профилей приложений на устройстве, выполните команду adb shell cmd package snapshot-profile android. Вы можете использовать агрегированную информацию в качестве основы для обработки и выбора метода/класса, не агрегируя вручную отдельные профили (хотя вы можете сделать это, если хотите).

Профиль загрузочного образа

Рисунок 1. Процесс получения профилей загрузочных образов

Данные профиля загрузочного образа

Профили загрузочных образов содержат следующие файлы и данные:

  • Профиль для загрузочного пути к классам (frameworks/base/config/boot-image-profile.txt). Определяет, какие методы из загрузочного пути к классам будут оптимизированы и какой класс будет включен в загрузочный образ .art.

  • Список предварительно загруженных классов. Определяет, какие классы будут предварительно загружены в Zygote.

  • Профиль для системных серверных компонентов (frameworks/base/services/art-profile). Определяет, какие методы из системного сервера будут оптимизированы или скомпилированы, какой класс будет включен в образ .art при загрузке и как будут размещены соответствующие DEX-файлы.

Формат профиля ART

Профиль ART содержит информацию из каждого загруженного DEX-файла, в том числе о методах, которые стоит оптимизировать, и классах, используемых при запуске. Если профилирование загрузочного образа включено, ART также добавляет в профиль путь к классам загрузки и JAR-файлы системного сервера и аннотирует каждый DEX-файл названием пакета, который его использует.

Например, выгрузите необработанный профиль загрузочного образа с помощью следующей команды:

adb shell profman --dump-only --profile-file=/data/misc/profman/android.prof

Вы увидите результат, похожий на следующий:

=== Dex files  ===
=== profile ===
ProfileInfo [012]

core-oj.jar:com.google.android.ext.services [index=0] [checksum=e4e3979a]
        hot methods: 520[], 611[] …
        startup methods: …
        classes: …
...
core-oj.jar:com.android.systemui [index=94] [checksum=e4e3979a]
        hot methods: 520[], 521[]…
        startup methods: …
        classes: …

В примере выше:

  • core-oj.jar используется в com.google.android.ext.services и com.android.systemui. В каждой записи перечислены два пакета, используемые из core-oj.jar.

  • В обоих процессах используется метод с индексом DEX 520, но только в процессе systemui используется метод с индексом DEX 521. Тот же принцип применяется к другим разделам профиля, например к классам запуска.

Во время обработки данных фильтруйте методы/классы на основе использования, отдавая приоритет процессам системного уровня (например, системному серверу или systemui) или методам, которые могут использоваться нечасто, но все равно важны (например, методам, используемым приложением камеры).

В формате профиля каждый метод аннотируется несколькими флагами (startup, post-startup, hotness, abi), которые не отображаются в формате dump-only. Чтобы использовать все сигналы, измените доступные скрипты.

Рекомендации

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

  • Разверните конфигурацию для создания профилей загрузочных образов на нескольких тестовых устройствах и соберите результаты, прежде чем создавать окончательный профиль загрузочного образа. Инструмент profman поддерживает агрегирование и выбор нескольких профилей загрузочного образа, но работает только с одной версией загрузочного образа (с одним и тем же путем к классам загрузки).

  • Отдавайте приоритет методам и классам, которые используются системными процессами. Эти методы/классы могут использовать код, который редко применяется в других приложениях, но все равно важен для оптимизации.

  • Форма данных, полученных при запуске на одном устройстве, сильно отличается от формы данных, полученных при тестировании реальных сценариев использования. Если у вас нет большого количества тестовых устройств, используйте одно и то же устройство для выполнения нескольких критических путей пользователя, чтобы повысить уверенность в том, что оптимизация профиля загрузочного образа будет хорошо работать в производственной среде (этот сценарий описан ниже).

Настройка устройств

Чтобы включить настройку профиля загрузки с помощью системных свойств, используйте один из следующих методов.

  • Вариант 1. Настройте свойства вручную (действует до перезагрузки):

    adb root
    adb shell stop
    adb shell setprop dalvik.vm.profilebootclasspath true
    adb shell setprop dalvik.vm.profilesystemserver true
    adb shell start
  • Вариант 2. Используйте local.prop (эффект будет действовать, пока файл не будет удален). Вот как это сделать:

    1. Создайте файл local.prop со следующим содержимым:

      dalvik.vm.profilebootclasspath=true
      dalvik.vm.profilesystemserver=true
      
    2. Выполните следующие команды:

      adb push local.prop /data/
      adb shell chmod 0750 /data/local.prop
      adb reboot
  • Вариант 3. Используйте конфигурацию устройства, чтобы задать следующие свойства на стороне сервера:

    adb shell device_config put runtime_native_boot profilebootclasspath true
    adb shell device_config put runtime_native_boot profilesystemserver true
    

Как создать профили загрузочных образов

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

  1. Настройте устройство.

    1. Настройте устройство, как описано в разделе Настройка устройств.

    2. (Необязательно.) Чтобы новый формат профиля очистил и заменил другие профили, требуется время. Чтобы ускорить сбор профилей, сбросьте все профили на устройстве.

      adb shell stop
      adb shell find "/data/misc/profiles -name *.prof -exec truncate -s 0 {} \;"
      adb shell start
    3. Запустите CUJ на устройстве.

  2. Чтобы записать профиль, используйте следующую команду:

    adb shell cmd package snapshot-profile android
  3. Извлеките профиль с помощью следующей команды:

    adb pull /data/misc/profman/android.prof
  4. Перейдите к JAR-файлам пути к классам загрузки, используя следующие команды:

    m dist
    ls $ANDROID_PRODUCT_OUT/boot.zip
  5. Создайте профиль загрузочного образа, используя следующую команду profman.

    profman --generate-boot-image-profile --profile-file=android.prof --out-profile-path=... --out-preloaded-classes-path=...
  6. Используя данные, настройте команду profman с помощью доступных флагов пороговых значений.

    • --method-threshold
    • --class-threshold
    • --clean-class-threshold
    • --preloaded-class-threshold
    • --upgrade-startup-to-hot
    • --special-package

    Полный список можно найти на странице в Справочном центре profman или в исходном коде.