Android ランタイムと Dalvik

Android ランタイム(ART)とは、Android 上のアプリや一部のシステム サービスが使用する管理対象ランタイムのことを指します。ART とその前身である Dalvik は、元々 Android プロジェクト用に作成されました。ART はランタイムとして、Dalvik 実行可能ファイル(DEX)形式と DEX バイトコード仕様を実行します。

ART と Dalvik は DEX バイトコードを実行する相互に互換性のあるランタイムであり、Dalvik 用に開発されたアプリは ART で実行しても動作します。ただし、Dalvik で機能する一部の手法は ART では機能しません。最も重要な問題については、Android ランタイム(ART)でのアプリの動作確認をご覧ください。

ART の機能

以下では、ART で実装される主な機能をいくつか紹介します。

事前(AOT)コンパイル

ART は、事前(AOT)コンパイルの導入によりアプリのパフォーマンスを改善します。また、ART では Dalvik よりインストール時の検証が厳格になっています。

インストール時に、ART はデバイス上の dex2oat ツールを使用してアプリをコンパイルします。このユーティリティは、DEX ファイルを入力として受け取り、ターゲット デバイスで実行可能なコンパイル済みアプリを生成します。すべての有効な DEX ファイルを簡単にコンパイルできます。ただし、一部の後処理ツールは、Dalvik では許容されても ART ではコンパイルできない無効なファイルを生成します。詳細については、ガベージ コレクションの問題への対応をご覧ください。

ガベージ コレクションの改善

ガベージ コレクション(GC)はリソースを大量に消費するため、アプリのパフォーマンスを低下させる可能性があり、その結果として、表示が途切れる、UI の応答が遅くなるなどの問題が生じます。ART では、次のようないくつかの方法でガベージ コレクションを改善しています。

  • GC の一時停止を 1 回にしてほぼ同時実行の設計にする
  • 同時コピーで、バックグラウンドでのメモリ使用量と断片化を削減する
  • GC の一時停止時間の長さをヒープサイズに依存させない
  • 最近割り当てられた短命なオブジェクトをクリーンアップする特殊なケースで、合計 GC 時間が短いコレクタを使用する
  • 人間工学の見地からガベージ コレクションを改善し、同時実行ガベージ コレクションをよりタイムリーに実行する(これにより、一般的なユースケースでは GC_FOR_ALLOC イベントがきわめてまれになります)

開発とデバッグの改善

ART には、アプリの開発とデバッグを改善するためのさまざまな機能があります。

サンプリング プロファイラのサポート

かつて、デベロッパーはプロファイラとして Traceview(アプリの実行をトレースするために設計されたツール)を使用していました。Traceview は有益な情報を提供しますが、Dalvik での結果はメソッドごとの呼び出しのオーバーヘッドによって歪曲され、このツールを使用すると実行時のパフォーマンスに大きく影響します。

ART では、こうした制限がない専用のサンプリング プロファイラのサポートが追加されました。これにより、パフォーマンスを著しく低下させることなく、アプリの実行をより正確に把握できます。サンプリングのサポートは、KitKat リリースで Dalvik 用の Traceview に追加されました。

より多くのデバッグ機能のサポート

ART は、特にモニタリングとガベージ コレクションに関連する機能において、いくつかの新しいデバッグ オプションをサポートしています。たとえば、次のようなことができます。

  • どのロックがスタック トレースに保持されているかを確認し、ロックを保持しているスレッドにジャンプします。
  • 特定のクラスに由来するライブ インスタンスの数を確認し、インスタンスを表示して、どの参照がオブジェクトをライブ状態に保っているかを確認します。
  • 特定のインスタンスのイベント(ブレークポイントなど)をフィルタリングします。
  • メソッドが終了時に返す値を(「method-exit」イベントにより)参照します。
  • フィールド ウォッチポイントを設定して、特定のフィールドがアクセス / 変更されたときにプログラムの実行を中断します。

例外レポートとクラッシュ レポートの診断情報の改善

ランタイム例外が発生すると、ART はできるだけ多くのコンテキストと詳細情報を提供します。ART は、java.lang.ClassCastExceptionjava.lang.ClassNotFoundExceptionjava.lang.NullPointerException について拡張された詳細な例外情報を生成します(Dalvik の最近のバージョンは java.lang.ArrayIndexOutOfBoundsExceptionjava.lang.ArrayStoreException について拡張された詳細な例外情報を生成しますが、これには配列のサイズと境界外のオフセットが含まれるようになりました。ART も同じ情報を提供します)。

たとえば、java.lang.NullPointerException は、null ポインタを使用してアプリが実行しようとしたオペレーションに関する情報(アプリが書き込みを試みたフィールドや呼び出しを試みたメソッドなど)を表示するようになりました。一般的な例を次に示します。

java.lang.NullPointerException: Attempt to write to field 'int
android.accessibilityservice.AccessibilityServiceInfo.flags' on a null object
reference
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String java.lang.Object.toString()' on a null object reference

また、ART では、アプリのネイティブ コードでのクラッシュ レポートのコンテキスト情報が改善され、Java とネイティブ スタックの両方の情報が含まれるようになりました。

問題を報告する

アプリの JNI が原因ではない問題に遭遇した場合は、Android オープンソース プロジェクトの Issue Tracker で報告してください。その際は、adb bugreport を報告に含めるとともに、Google Play ストアにアプリがある場合はそのリンクも記載してください。Google Play ストアにアプリがない場合は、可能であれば、問題を再現する APK を添付してください。