Android ランタイム(ART)は、Android 搭載デバイス向けのデフォルトのランタイムです。 5.0(API レベル 21)以降。このランタイムには Android プラットフォームとアプリのパフォーマンスとスムーズさを向上させています。 ART の新機能について詳しくは、 ART。
ただし、Dalvik で機能する一部の手法は ART では機能しません。この で、既存の VM プロバイダを移行する際に注意すべき点について 対応する必要があります。ほとんどのアプリは、Google Compute Engine で実行されている ART。
ガベージ コレクション(GC)の問題に対処する
Dalvik では、アプリが明示的に呼び出しを行うと、
System.gc()
: ガベージ コレクション(GC)を要求します。これを
ART を使用する場合(特にガベージ コレクションを呼び出す場合)
GC_FOR_ALLOC
タイプの
断片化を減らすために重要です使用中のランタイムと
System.getProperty("java.vm.version")
を呼び出します。ART が使用されている場合、プロパティの値
"2.0.0"
以上。
ART は、Java ヒープを同時に圧縮する同時コピー(CC)コレクタを使用します。 そのため、Terraform のような手法は使用しないでください。 GC の圧縮と互換性がない(オブジェクトへのポインタの保存など) インスタンス データなど)が含まれます。これは、 JNI(Java Native Interface)詳しくは、JNI の問題の防止をご覧ください。
JNI の問題の防止
ART の JNI は、Dalvik の JNI よりやや厳格です。これは特に CheckJNI モードを使用して一般的な問題をキャッチします。アプリで C/C++ 次の記事をご覧ください。
デバッグ Android JNI と CheckJNI の使用
JNI コードでガベージ コレクションの問題を確認する
同時コピー(CC)コレクタは、コンパクションのためにメモリ内のオブジェクトを移動することがあります。 C/C++ コードを使用する場合は、 GC の圧縮と互換性のない操作を実行する。Google は、 CheckJNI で潜在的な問題を特定(JNI を参照) ローカル参照の変更(ICS)をご覧ください)。
特に注目すべき領域の一つは
Get...ArrayElements()
および Release...ArrayElements()
使用できます。圧縮されていない GC を使用するランタイムでは、
Get...ArrayElements()
関数は通常、
配列オブジェクトの背後にある実際のメモリです。リージョンまたは
返された配列要素がある場合、配列オブジェクト自体が変更され
Release...ArrayElements()
までは無視されます)。ただし、
GC の圧縮が使用されている場合、Get...ArrayElements()
関数が
メモリのコピーを返します。GC の圧縮時に参照を誤って使用すると、
メモリ破損などの問題が発生する可能性があります。例:
- 返された配列要素に変更を加えた場合、
適切な
Release...ArrayElements()
関数を実行します。 元のアカウントに変更内容が正しくコピーされ、 配列オブジェクトです。 - メモリ配列要素を解放するときは、
次のモードになります。
<ph type="x-smartling-placeholder">
- </ph>
- 配列要素を変更していない場合は、次のコマンドを使用します。
JNI_ABORT
モード: コピーせずにメモリを解放します。 基になる配列オブジェクトに戻ります - 配列に変更を加えて、参照が不要な場合は、
さらに、コード
0
を使用します(配列オブジェクトが更新され、 。 - commit する配列に変更を加えて、
配列のコピーを保持するには、
JNI_COMMIT
を使用します(これにより、 コピーを保持します)。
- 配列要素を変更していない場合は、次のコマンドを使用します。
Release...ArrayElements()
を呼び出すと、同じ 最初にGet...ArrayElements()
によって返されたポインタ。対象 元のポインタをインクリメントすることは安全ではありません( 戻された配列要素)を渡して、増分されたポインタをRelease...ArrayElements()
。この変更されたポインタを渡すと、 間違ったメモリが解放され、メモリ破損につながります。
エラー処理
ART の JNI はエラーをスローするケースが多く、Dalvik ではスローされません。(1 回 このようなケースの多くは、CheckJNI でテストすることで捕捉できます)。
たとえば、RegisterNatives
が呼び出されるメソッドが、
存在しない(メソッドが
ProGuard)により、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()
が NoSuchFieldError
を適切にスローするようになりました
単純に null を返すのではなく、同様に、GetMethodID()
と
GetStaticMethodID()
が NoSuchMethodError
を適切にスローするようになりました。
これにより、未処理の例外や
ネイティブ コードの Java 呼び出し元には例外がスローされます。これにより、
CheckJNI モードで ART 互換アプリをテストする場合は特に重要です。
ART は JNI CallNonvirtual...Method()
メソッドのユーザーを想定
(CallNonvirtualVoidMethod()
など)を使用して、メソッドの宣言を使用する
クラス(サブクラスではなく)を使用します。
スタックサイズの問題の防止
Dalvik には、ネイティブ コードと Java コード用に別々のスタックがあり、
スタックサイズは 32 KB、デフォルトのネイティブ スタックサイズは 1 MB です。ART は
スタックを使用しています。通常、ART Thread
スタックは
Dalvik の場合とほぼ同じサイズにする必要があります。ただし、明示的に
スタックサイズを設定するため、Google Cloud で実行するアプリでは、
ART。
- Java で、明示的なスタックを指定する
Thread
コンストラクタの呼び出しを確認する 指定します。たとえば、StackOverflowError
が発生した場合は、サイズを増やす必要があります。 - C/C++ での
pthread_attr_setstack()
の使用と Java コードも実行するスレッドの場合はpthread_attr_setstacksize()
JNI です。アプリが JNI を呼び出そうとしたときにログに記録されるエラーの例を以下に示します。AttachCurrentThread()
: pthread サイズが小さすぎる場合:F/art: art/runtime/thread.cc:435] Attempt to attach a thread with a too-small stack (16384 bytes)
オブジェクト モデルの変更
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
に非公開フィールドが追加されました。野外活動を振り返るアプリ
自分のクラス階層内の他のグループを見てみると、
Object
のフィールド。たとえば、あるクラスを反復処理する
階層構造をシリアライゼーション フレームワークの一部として組み込むと、
Class.getSuperclass() == java.lang.Object.class
メソッドが null
を返すまで続行するのではなく、
存在しない場合、プロキシ InvocationHandler.invoke()
は null
を受け取るようになりました。
引数を渡します。この動作はすでに文書化されていますが、
Dalvik では正しく処理されません以前のバージョンの Mockito では、
そのため、ART でテストする際は最新の Mockito バージョンを使用してください。
AOT コンパイルの問題の解決
ART の事前(AOT)Java コンパイルは、すべての標準 Java で機能する
できます。コンパイルは ART の
dex2oat
ツール関連する問題が発生した場合に
インストール時に dex2oat
された場合は、Google までお知らせください(問題の報告を参照)。速やかに修正いたします
必要があります。注意すべき問題がいくつかあります。
- ART では、インストール時のバイトコード検証が Dalvik よりも厳格になっています。 Android ビルドツールによって生成されたコードは問題ありません。ただし、 後処理ツール(特に難読化を実行するツール)が原因で、 Dalvik では許容されるが ART では拒否される無効なファイル私たちは ツールベンダーと協力してこのような問題を見つけて修正します多くの場合、 DEX ファイルを再生成すると、これらの問題を修正できます 学習します
- ART 検証ツールで報告される一般的な問題には、次のようなものがあります。
<ph type="x-smartling-placeholder">
- </ph>
- 無効な制御フロー
- 不均衡:
monitorenter
/monitorexit
- 長さ 0 のパラメータ型のリストサイズ
- 一部のアプリは、インストールされた
.odex
ファイルと依存関係があります 形式は/system/framework
、/data/dalvik-cache
、DexClassLoader
の最適化された出力ディレクトリ。これらの ファイルは拡張形式の DEX ファイルではなく、ELF ファイルになりました。ART が試行している間 ルールに従うため、アプリは Dalvik に依存せず、 制限します。形式は予告なく変更される場合があります。注: Android 8.0(API レベル 26)と それより上位の、
DexClassLoader
の最適化された出力ディレクトリ サポートが終了しました。詳細については、このモジュールのDexClassLoader()
コンストラクタがあります。
問題の報告
アプリの JNI の問題が原因ではない問題に遭遇した場合は、
Android オープンソース プロジェクトの Issue Tracker(https://code.google.com/p/android/issues/list)から配布できます。
"adb bugreport"
と、Google
Play ストア(利用可能な場合)。それ以外の場合は、可能であれば、問題を再現する APK を
解決します。問題(添付ファイルを含む)は一般公開されることに注意してください
表示されます。