Skip to content

Most visited

Recently visited

navigation

Android ランタイム (ART) でアプリ動作を確認

Android ランタイム(ART)は、Android 5.0(API レベル 21)以降を実行している端末のデフォルトのランタイムです。 このランタイムは、Android プラットフォームおよびアプリのパフォーマンスと動作の滑らかさを向上させる多くの機能を提供します。 ART の新しい機能の詳細については、ART の紹介を参照してください。

ただし、Dalvik で動作する一部の技術は ART では動作しません。このドキュメントでは、既存のアプリを移行して ART と互換性を持たせる際の注意点について説明しています。 大半のアプリは、ART と適切に連動するはずです。

ガベージ コレクション(GC)の問題への対応

Dalvik では、多くの場合、アプリで明示的に System.gc() を呼び出して、ガベージ コレクション(GC)を実行すると便利です。ART では、特に GC_FOR_ALLOC タイプの発生を防止するために、または断片化を削減するためにガベージ コレクションを呼び出す場合に、こうした明示的な呼び出しを行う必要はほとんどありません。 System.getProperty("java.vm.version") を呼び出すと、使用されているランタイムを確認することができます。 ART が使用されている場合、プロパティの値は "2.0.0" 以上になります。

さらに、Android オープンソース プロジェクト(AOSP)では、メモリ管理機能を改善するために、コンパクションを行うガベージ コレクターを開発しています。 そのため、GC の圧縮と互換性のない技術(オブジェクトのインスタンス データへのポインタを保存することなど)の使用を避ける必要があります。 これは、Java Native Interface(JNI)を使用するアプリでは特に重要です。 詳細については、JNI の問題の防止を参照してください。

JNI の問題の防止

ART の JNI は、Dalvik の JNI よりも若干厳密です。一般的な問題の検出には CheckJNI モードを使用することをお勧めします。 アプリで C/C++ コードを使用している場合は、次の記事を確認してください

CheckJNI を使った Android JNI のデバッグ

ガベージ コレクションの問題に対応するために JNI コードを確認

ART には、Android オープンソース プロジェクト(AOSP)で開発中のコンパクション対応のガベージ コレクション機能が備わっています。 ガベージ コレクションの圧縮を使用すると、オブジェクトをメモリに移動することができます。 C/C++ コードを使用している場合は、GC の圧縮と互換性のない操作を実行しないでください。 Google では CheckJNI を強化して、いくつかの潜在的な問題を検出できるようにしています(ICS の JNI ローカル リファレンスの変更点で説明しています)。

特に注意が必要なのは、Get...ArrayElements() 関数と Release...ArrayElements() 関数を使用する場面です。 コンパクション非対応の GC を備えたランタイムでは、通常、Get...ArrayElements() 関数により、配列オブジェクトをバックアップする実際のメモリへの参照が返されます。 返された配列要素のいずれかに変更を加えた場合、配列オブジェクト自体が変更されます(通常、Release...ArrayElements() の引数は無視されます)。 ただし、コンパクション対応の GC を使用している場合は、Get...ArrayElements() 関数がメモリのコピーを返すことがあります。 コンパクション対応の GC を使用しているときに参照を誤用すると、メモリの破損やその他の問題が発生する可能性があります。 次に例を示します。

エラー処理

ART の JNI は、多くのケース(Dalvik ではエラーがスローされない)でエラーをスローします(繰り返しますが、CheckJNI でテストすることにより、そのような多くのケースを検出することができます)。

たとえば、存在しないメソッド(ProGuard などのツールでメソッドが削除されている場合など)で RegisterNatives を呼び出すと、ART は NoSuchMethodError を適切にスローします。

08-12 17:09:41.082 13823 13823 E AndroidRuntime: FATAL EXCEPTION: main
08-12 17:09:41.082 13823 13823 E AndroidRuntime: java.lang.NoSuchMethodError:
    no static or non-static method
    "Lcom/foo/Bar;.native_frob(Ljava/lang/String;)I"
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.nativeLoad(Native Method)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.doLoad(Runtime.java:421)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.loadLibrary(Runtime.java:362)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.System.loadLibrary(System.java:526)

メソッドなしで RegisterNatives が呼び出された場合も、ART はエラー(logcat に表示される)をログに記録します。

W/art     ( 1234): JNI RegisterNativeMethods: attempt to register 0 native
methods for <classname>

また、JNI 関数の GetFieldID()GetStaticFieldID() は現在、単に null を返す代わりに、NoSuchFieldError を適切にスローします。 同様に、GetMethodID()GetStaticMethodID() は現在、NoSuchMethodError を適切にスローします。これにより、例外が未処理になったり、ネイティブ コードの Java 呼び出し元に例外がスローされたりするため、CheckJNI の失敗が発生する可能性があります。 つまり、CheckJNI モードで ART 対応アプリをテストすることが特に重要になります。

ART では、JNI CallNonvirtual...Method() メソッド(CallNonvirtualVoidMethod() など)のユーザーは、JNI の仕様で求められているように、メソッドのサブクラスではなく、宣言クラスを使用する必要があります。

スタックサイズの問題の防止

Dalvik には、ネイティブ コードと Java コード用の個別のスタックがあります。デフォルトの Java スタックのサイズは 32KB で、デフォルトのネイティブ スタックのサイズは 1MB です。 ART はローカル性を高めるための統合スタックを備えています。 通常、ART Thread スタックのサイズは、Dalvik のスタックとほぼ同じサイズにする必要があります。 ただし、明示的にスタックのサイズを設定している場合は、ART で実行されているアプリ向けにそれらの値を再検討する必要があることがあります。

オブジェクト モデルの変更

Dalvik では、package-private メソッドのオーバーライドをサブクラスに不適切に許可していました。このような場合、ART は警告を発行します。

Before Android 4.1, method void com.foo.Bar.quux()
would have incorrectly overridden the package-private method in
com.quux.Quux

異なるパッケージでクラスのメソッドをオーバーライドする場合は、メソッドを public または protected として宣言します。

現在、Object には private フィールドがあります。クラス階層のフィールドに反映されるアプリでは Object のフィールドを検索しないように注意する必要があります。 たとえば、シリアル化フレームワークの一部としてクラス階層を反復しているときは、次の場合に停止してください。

Class.getSuperclass() == java.lang.Object.class
メソッドが null を返すまで継続してはなりません。

現在、プロキシ InvocationHandler.invoke() は、引数がない場合に、空の配列ではなく、null を受け取ります。 この動作は既にドキュメント化されていますが、Dalvik では適切に処理されません。 前のバージョンの Mockito ではこの処理が困難なため、ART でテストを行うときは、アップデートされた Mockito バージョンを使用してください。

AOT コンパイルの問題の修正

ART の Ahead-Of-Time(AOT)Java コンパイルは、標準のすべての Java コードに対して機能するはずです。 コンパイルは、ART の dex2oat ツールによって実行されます。インストール時に dex2oat に関連する問題が発生した場合は、問題を可能な限り迅速に修正しますので、Google までお知らせください(問題の報告をご覧ください)。 次のようないくつかの問題に注意してください。

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a one-minute survey?
Help us improve Android tools and documentation.