いくつかの状況でガベージコレクターを呼び出すことを提案する多くのAndroid回答を見てきました。
メモリを大量に消費する操作を行う前に、Androidのガベージコレクタを要求することをお勧めしますか?そうでない場合、OutOfMemory
エラーが発生した場合にのみ呼び出す必要がありますか?
ガベージコレクターに頼る前に他に使用すべきものはありますか?
.0ハニカムより前のバージョンの場合:はい、呼び出しを行うSystem.gc()
。
ビットマップを作成しようとしましたが、常に「VM out of memoryエラー」が発生していました。しかし、System.gc()
を最初に呼び出したときは問題ありませんでした。
ビットマップを作成するとき、Androidはメモリ不足エラーで失敗することが多く、最初にガベージコレクションを試行しません。したがって、System.gc()
を呼び出すと、ビットマップを作成するのに十分なメモリがあります。
オブジェクトを作成する場合、System.gc
は必要に応じて自動的に呼び出されますが、ビットマップの作成ではnotと考えられます。ただ失敗するだけです。
したがって、ビットマップを作成する前に、System.gc()
を手動で呼び出すことをお勧めします。
一般的に、ガベージコレクタが存在する場合、GCを手動で呼び出すことはneverの良い習慣です。 GCは、独自のデバイスに任せたときに最適に機能するヒューリスティックアルゴリズムを中心に構成されています。 GCを手動で呼び出すと、多くの場合パフォーマンスが低下します。
時々、比較的まれな状況では、特定のGCが間違っていることがわかり、GCを手動で呼び出すとパフォーマンスが向上する場合があります。これは、すべての場合でメモリを最適に管理する「完璧な」GCを実装することが実際には不可能だからです。そのような状況は予測が難しく、多くの微妙な実装の詳細に依存します。 「グッドプラクティス」は、GCを単独で実行することです。 GCへの手動呼び出しは例外であり、実際のパフォーマンスの問題が適切に目撃された後にのみ想定する必要があります。
ビットマップを適切に処理しない場合、Androidアプリケーションのメモリ不足は非常に一般的です。問題の解決策は
if(imageBitmap != null) {
imageBitmap.recycle();
imageBitmap = null;
}
System.gc();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
imageBitmap = BitmapFactory.decodeFile(URI, options);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 200, true);
imageView.setImageBitmap(scaledBitmap);
上記のコードでは、使用したメモリスペースを解放できるビットマップをリサイクルしようとしましたので、メモリ不足が発生しない可能性があります。
それでも問題が解決しない場合は、これらの行も追加できます
BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16*1024];
options.inPurgeable = true;
詳細については、このリンクをご覧ください
http://voices.yahoo.com/Android-virtual-machine-vm-out-memory-error-7342266.html
注:gcの実行によって一時的に発生する「一時停止」のため、noteachビットマップ割り当ての前にこれを行うことをお勧めします。
最適な設計は次のとおりです。
無料不要になったすべてのビットマップ、表示されるif / recycle / null
code。 (それを支援するメソッドを作成します。)
System.gc();
新しいビットマップを割り当てます。
OutOfMemoryErrorが発生した場合、通常はガベージコレクターを呼び出すには遅すぎます...
Android Developerからの引用:
ほとんどの場合、ガベージコレクションは、多数の小さく短命のオブジェクトのために発生し、世代別ガベージコレクタなどの一部のガベージコレクタは、アプリケーションが頻繁に中断されないように、これらのオブジェクトのコレクションを最適化できます。残念ながらAndroidガベージコレクターはこのような最適化を実行できないため、パフォーマンスが重要なコードパスに短命のオブジェクトを作成すると、アプリケーションのコストが非常に高くなります。
私の理解では、gcを呼び出す必要はありません。オブジェクトの不必要な作成(ループ内でのオブジェクトの作成など)を避けるために、より多くの労力を費やす方がよい
私のアプリは多くの画像を管理し、OutOfMemoryErrorで死にました。これは私を助けました。 Manifest.xmlで追加
<application
....
Android:largeHeap="true">
アートAndroid 6.0.1 Nexus 5xではSystem.gc()
が機能しないようです。そのため、代わりにRuntime.getRuntime().gc();
を使用します。
一般的に、System.gc()でGCを明示的に呼び出すべきではありません。 IO講義( http://www.youtube.com/watch?v=_CruQY55HOk )もあり、GC一時停止ログの意味を説明します。 System.gc()を絶対に呼び出さない状態。Dalvikはいつ呼び出すかを知っているからです。
一方、上記の回答で述べたように、AndroidのGCプロセス(他のすべてのものと同様)にはバグがある場合があります。これは、Dalvik GCアルゴリズムがHotspotまたはJRockit JVMと同等ではなく、場合によっては問題が発生する可能性があることを意味します。それらの機会の1つは、ビットマップオブジェクトを割り当てるときです。これは、ヒープメモリと非ヒープメモリを使用し、メモリが制限されたデバイス上のビットマップオブジェクトの1つのゆるいインスタンスでOutOfMemory例外が発生するため、扱いにくいものです。したがって、このビットマップが不要になった後に呼び出すことは、多くの開発者によって一般的に提案されており、一部の人々によっては良い習慣と見なされています。
ビットマップのネイティブメモリを削除しても安全であるとマークするため、このメソッドの目的であるビットマップで.recycle()を使用することをお勧めします。これは非常にバージョンに依存していることに注意してください。つまり、一般的に古いAndroidバージョン(3.0以前のバージョン)では必要ですが、それ以降のバージョンでは必要ありません。また、新しいバージョンのエーテルでそれを使用してもそれほど害はありません(ループなどでこれを行わないでください)。新しいARTランタイムは、ビッグオブジェクト用の特別なヒープ「パーティション」を導入したため、ここで大きく変わりましたが、ARTエーテルでこれを実行してもそれほど害はないと思います。
また、System.gc()に関する1つの非常に重要な注意事項。このメソッドは、Dalvik(またはJVM)が応答する必要があるコマンドではありません。仮想マシンに「手間がかからない場合はガベージコレクションを行ってください」と言うようなものだと考えてください。
ビットマップ作成中にOOMを回避する最良の方法、
http://developer.Android.com/training/displaying-bitmaps/index.html
OutOfMemoryError
の後にガベージコレクターを呼び出す必要はありません。
Javadocには次のように明記されています。
Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.
そのため、ガベージコレクターは、エラーを生成する前に既にメモリを解放しようとしましたが、失敗しました。
...
GC_EXPLICIT
gc() (whichする必要があるavoidcalling代わりに、必要に応じてGCが実行されることを信頼します。
...
関連する部分を太字で強調しました。
YouTubeシリーズをご覧ください Android Performance Patterns -アプリのメモリ使用量を管理するためのヒントが表示されます(AndroidのArrayMap
sとSparseArray
sではなくHashMap
s)。
Xamarin開発者のクイックノート。
Xamarin.AndroidアプリでSystem.gc()
を呼び出したい場合は、Java.Lang.JavaSystem.Gc()
を呼び出す必要があります