Android ランタイム(ART)には、実行中の Android アプリのパフォーマンスを継続的に改善するコード プロファイリングを備えた、ジャストインタイム(JIT)コンパイラが含まれています。JIT コンパイラは、ART の現行の事前(AOT)コンパイラを補完し、ランタイムのパフォーマンスの改善、ストレージ容量の節約、アプリとシステムのアップデートの高速化を実現します。また、アプリの自動アップデート中のシステム シャットダウンや無線(OTA)アップデート中のアプリの再コンパイルを回避することで、AOT コンパイラのパフォーマンスも改善します。
JIT と AOT は同じコンパイラを使用して同様の最適化セットを実施しますが、生成されるコードは同じとは限りません。JIT はランタイム型の情報を利用するとともに、より適切なインライン化を行い、また、オンスタック置換(OSR)コンパイルを可能にします。これらすべての結果として、わずかに異なるコードが生成されます。
JIT のアーキテクチャ
JIT コンパイル
JIT コンパイルは次のアクティビティで構成されます。
- ユーザーがアプリを実行すると、ART がトリガーされて
.dex
ファイルが読み込まれます。.oat
ファイル(.dex
ファイルの AOT バイナリ)が使用できる場合、ART は直接それを使用します。.oat
ファイルは定期的に生成されますが、コンパイル済みコード(AOT バイナリ)を含むとは限りません。.oat
ファイルにコンパイル済みコードが含まれていない場合は、ART が JIT とインタープリタを使用して.dex
ファイルを実行します。
speed
コンパイル フィルタ(「できる限りアプリからコンパイルする」ことを指定します)に従ってコンパイルされていないすべてのアプリで、JIT が有効化されます。- JIT プロファイル データは、アプリだけがアクセスできるシステム ディレクトリ内のファイルにダンプされます。
- AOT コンパイル(
dex2oat
)デーモンは、コンパイルを進めるためにそのファイルを解析します。
図 3. JIT デーモンのアクティビティ
共有ライブラリと同様に動作する別のアプリで使用される例としては、Google Play 開発者サービスがあります。
JIT のワークフロー
- プロファイリング情報はコード キャッシュに格納され、メモリ不足の状況ではガベージ コレクションの対象になります。
- アプリがバックグラウンドで実行されたときに取得されたスナップショットに、完全なデータ(JIT コンパイルされたすべてのデータ)が含まれる保証はありません。
- すべてのデータを記録しようとするとランタイムのパフォーマンスに影響するため、完全な記録は保証されません。
- メソッドには次の 3 つの状態があります。
- 解釈済み(dex コード)
- JIT コンパイル済み
- AOT コンパイル済み
- フォアグラウンド アプリのパフォーマンスに影響を与えずに JIT を実行するためのメモリ要件は、該当のアプリによって異なります。サイズが大きいアプリは小さいアプリより多くのメモリを必要とします。一般的に、大きいアプリはおよそ 4 MB で動作が安定します。
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
注: このコマンドを実行しても、ローカルのプロファイル データは保持されます。