Android 11 以降は、ブートイメージ プロファイルの生成をサポートしています。ブートイメージ プロファイルは、システム サーバーやブート クラスパスなど、さまざまなシステムレベル コンポーネントのコードに関する情報をカプセル化します。Android ランタイム(ART)は、この情報を使用してシステム全体を最適化します。この最適化の一部は Android のパフォーマンスにとって非常に重要であり、すべての非ネイティブ コード(システムレベルおよびアプリレベル)の実行に影響を与えます。ブートイメージ プロファイルを使用することで、実行パフォーマンスやメモリ消費量に 2 桁の改善率が見られる場合もあります。
ブート プロファイル情報を取得する
ブートイメージ プロファイルは、クリティカル ユーザー ジャーニー(CUJ)の間に実行されたアプリのプロファイルから取得されます。特定のデバイス設定では、ART はアプリで使用されるブート クラスパスのメソッドとクラスを(JIT プロファイルの一部として)キャプチャし、その情報をアプリのプロファイル(たとえば、/data/misc/profiles/cur/0/com.android.chrome/primary.prof
)に記録します。アプリのプロファイル内の情報には、ブート クラスパス Dalvik EXecutable(DEX)ファイルのインデックスが付加されます(ART プロファイルの形式をご覧ください)。
CUJ の間に記録されたアプリ プロファイルを確認して、ブート クラスパスの中で使用頻度が高く、最適化すべき重要な部分を特定します(例については、ART プロファイルの形式をご覧ください)。すべてのメソッドやクラスを含めるとパフォーマンスに悪影響を与えるため、使用頻度の高いコードパスに絞るようにします。たとえば、1 つのアプリにのみ使用されているブート クラスパスのメソッドは、ブート プロファイルに含めるべきではありません。各デバイスでのメソッドやクラスの選択は、CUJ の選択とテストで生成されたデータの量に基づいて設定する必要があります。
デバイス上のすべてのアプリ プロファイルからブート クラスパス情報を集約するには、adb shell cmd package snapshot-profile android
コマンドを実行します。この集約された情報は、処理やメソッドやクラスの選択の際に基本情報として役立ち、個々のプロファイルを手動で集約する必要もなくなります(必要な場合は手動でも集約できます)。
図 1. ブートイメージ プロファイルの取得プロセス
ブートイメージ プロファイル データ
ブートイメージ プロファイルには、次のファイルとデータが含まれます。
ブート クラスパスのプロファイル(
frameworks/base/config/boot-image-profile.txt
)。最適化するブート クラスパスのメソッド、ブート.art
イメージに含めるクラス、および対応する DEX ファイルの配置方法を指定します。プリロードするクラスのリスト。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
から使用されている 2 つのパッケージがリストされています。どちらのプロセスも DEX インデックス 520 のメソッドを使用していますが、DEX インデックス 521 のメソッドを使用しているのは
systemui
プロセスのみです。他のプロファイル セクション(startup クラスなど)の解釈方法も同じです。
データ処理の時点で、使用状況に基づいてメソッドやクラスをフィルタし、システムレベルのプロセス(システム サーバーや systemui
など)や、あまり使われないながらも重要なメソッド(カメラアプリに使用されるメソッドなど)を優先します。
ART プロファイル形式の内部では、dump-only 形式で表示されるよりも多くの種類のフラグ(startup、post-startup、hotness、abi)が、各メソッドにアノテーションとして付けられています。すべてのシグナルを利用するには、用意されているスクリプトを変更します。
推奨事項
よい結果を得るためには、以下のガイドラインに準拠してください。
ブートイメージ プロファイルを生成するための設定を複数のテストデバイスにデプロイし、結果を集約してから最終的なブートイメージ プロファイルを生成します。なお、
profman
ツールは複数のブートイメージ プロファイルの集約と選択をサポートしていますが、同じバージョンのブートイメージ(同じブート クラスパス)でのみ機能します。システム プロセスで使用されるメソッドやクラスに選択の優先順位を設定します。それらのメソッドやクラスには、他のアプリではあまり使用されないながらも最適化すべき、重要なコードが含まれる場合があります。
1 台のデバイスのみで実行する場合に得られるデータの形状は、実際に CUJ を実行する複数のテストデバイスから得られるものと大きく異なります。多数のテストデバイスを用意できない場合は、同じデバイスで複数の CUJ を実行することにより、本番環境で効果が得られるようにブートイメージ プロファイル最適化の信頼性を高めます(このシナリオについては下記で説明します)。
デバイスを設定する
システム プロパティを使用してブート プロファイル設定を有効にするには、以下の方法のいずれかを使用します。
方法 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
を使用します(ファイルが削除されるまで永続的に有効です)。手順は以下のとおりです。次の内容の
local.prop
ファイルを作成します。dalvik.vm.profilebootclasspath=true dalvik.vm.profilesystemserver=true
次のコマンドを実行します。
adb push local.prop /data/
adb shell chmod 0750 /data/local.prop
adb reboot
方法 3: デバイス設定を使用して、次のサーバー側プロパティを設定します。
persist.device_config.runtime_native_boot.profilesystemserver persist.device_config.runtime_native_boot.profilebootclasspath`
ブートイメージ プロファイルを生成する
次の手順を使用して、1 台のデバイスでのテストから基本的なブートイメージ プロファイルを生成します。
デバイスをセットアップします。
デバイスの設定で説明した方法でデバイスを設定します。
(任意)他のプロファイルが消去されて新しいプロファイル形式に置き換わるには時間がかかります。プロファイル収集の速度を上げるには、デバイス上のすべてのプロファイルをリセットします。
adb shell stop
adb shell find "/data/misc/profiles -name *.prof -exec truncate -s 0 {} \;"
adb shell start
デバイスで CUJ を実行します。
次のコマンドを使用してプロファイルをキャプチャします。
adb shell cmd package snapshot-profile android
次のコマンドを使用してプロファイルを抽出します。
adb pull /data/misc/profman/android.prof
次のコマンドを使用して、ブート クラスパス JAR ファイルに移動します。
m dist
ls $ANDROID_PRODUCT_OUT/boot.zip
次の
profman
コマンドを使用して、ブートイメージ プロファイルを生成します。profman --generate-boot-image-profile --profile-file=android.prof --out-profile-path=... --out-preloaded-classes-path=...
データを使用して、利用可能な選択しきい値フラグで
profman
コマンドを調整します。--method-threshold
--class-threshold
--clean-class-threshold
--preloaded-class-threshold
--upgrade-startup-to-hot
--special-package
完全なリストについては、
profman
ヘルプページまたはソースコードをご覧ください。