回答:
3.0ハニカムより前のバージョンの場合:はい、電話してください System.gc()
。
ビットマップを作成しようとしましたが、常に「メモリ不足エラー」が発生していました。しかし、私が電話したときSystem.gc()
最初は大丈夫でした。
ビットマップを作成するとき、Androidはメモリ不足エラーで失敗することが多く、ガベージコレクションを最初に試みません。したがって、System.gc()
、ビットマップを作成するのに十分なメモリがあります。
オブジェクトを作成するSystem.gc
場合、必要に応じて自動的に呼び出されると思いますが、そうではありませんビットマップを作成する。失敗するだけです。
したがってSystem.gc()
、ビットマップを作成する前に手動で呼び出すことをお勧めします。
一般的に、ガベージコレクターが存在する場合、GCを手動で呼び出すことはお勧めできません。GCはヒューリスティックアルゴリズムを中心に構成されており、独自のデバイスに任せたときに最適に機能します。GCを手動で呼び出すと、パフォーマンスが低下することがよくあります。
ときどき、比較的まれな状況で、特定のGCが間違っていることに気づき、GCを手動で呼び出すと、パフォーマンスが向上することがあります。これは、すべてのケースでメモリを最適に管理する「完全な」GCを実装することは実際には不可能だからです。このような状況は予測が難しく、多くの微妙な実装の詳細に依存しています。「良い習慣」は、GCを単独で実行することです。GCへの手動呼び出しは例外です。これは、実際のパフォーマンスの問題が正式に確認された後にのみ想定する必要があります。
Bitmap.finalize()
ます(非VMメモリを解放するメソッドが実行されます)。したがって、この場合には、あなたがすべき GCの頭やオーバーラン行くBitmap.recycle()
か、System.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;
詳細については、このリンクをご覧ください
注:GCの実行によって引き起こされるため、瞬間的に「一時停止」、されていない前にこれを実行することをお勧めし、各ビットマップの割り当て。
最適な設計は次のとおりです。
示されているコードによって、不要になったすべてのビットマップを解放しますif / recycle / null
。(それを助ける方法を作ってください。)
System.gc();
新しいビットマップを割り当てます。
OutOfMemoryErrorが発生した場合、通常はガベージコレクターを呼び出すには遅すぎます...
Android Developerからの引用は次のとおりです。
ほとんどの場合、ガベージコレクションは、大量の小さな短期間のオブジェクトが原因で発生します。世代別ガベージコレクターなどの一部のガベージコレクターは、アプリケーションが頻繁に中断されないように、これらのオブジェクトのコレクションを最適化できます。残念ながら、Androidガベージコレクターはこのような最適化を実行できません。したがって、パフォーマンスが重要なコードパスで短期間のオブジェクトを作成すると、アプリケーションのコストが非常に高くなります。
したがって、私の理解では、gcを呼び出す必要はありません。不要なオブジェクトの作成(ループ内のオブジェクトの作成など)を回避するために、より多くの労力を費やすことをお勧めします。
私のアプリは多くの画像を管理していますが、OutOfMemoryErrorで終了しました。これは私を助けました。Manifest.xmlに追加
<application
....
android:largeHeap="true">
一般的に言えば、System.gc()で明示的にGCを呼び出すべきではありません。IO講義(http://www.youtube.com/watch?v=_CruQY55HOk)もあり、GCの一時停止ログの意味と、Dalvikの方が知っているのでSystem.gc()を呼び出さないように説明しています。あなたよりそうするとき。
一方、上記で述べたように、AndroidのGCプロセス(他のすべてと同様)にはバグがある場合があります。つまり、Dalvik GCアルゴリズムはHotspotまたはJRockit JVMと同等ではなく、場合によっては問題が発生する可能性があります。それらの状況の1つは、ビットマップオブジェクトを割り当てるときです。これは、ヒープメモリと非ヒープメモリを使用し、メモリに制約のあるデバイス上のビットマップオブジェクトの1つの緩やかなインスタンスでOutOfMemory例外を発生させるのに十分なため、トリッキーです。そのため、このビットマップが不要になった後に呼び出すことは、一般に多くの開発者によって提案されており、一部の人々によっては良い習慣と見なされています。
ビットマップのネイティブメモリを安全に削除できるとマークされているため、ビットマップで.recycle()を使用することをお勧めします。これは非常にバージョンに依存していることを覚えておいてください。つまり、通常は古いバージョンのAndroid(3.0以前と思う)では必要ですが、それ以降のバージョンでは必要ありません。また、新しいバージョンのetherでそれを使用してもそれほど害はありません(これをループなどで実行しないでください)。新しいARTランタイムは、大きなオブジェクト用に特別なヒープ「パーティション」を導入したため、ここで大きく変化しましたが、ARTエーテルでこれを行うことはそれほど害にはならないと思います。
また、System.gc()に関する非常に重要な注意事項の1つです。このメソッドは、Dalvik(またはJVM)が応答する義務があるコマンドではありません。それは、仮想マシンに「面倒ではない場合はガベージコレクションを実行していただけませんか」と言うようなものだと考えてください。
ビットマップの作成中にOOMを回避する最良の方法は、
http://developer.android.com/training/displaying-bitmaps/index.html
RAMの使用状況に関する開発者ドキュメントは次のとおりなので、私はノーと言います。
...
GC_EXPLICIT
そのようなあなたが呼び出すときのように、明示的なGC、GC() (あなたがすべき避ける呼び出す代わりに、必要なときに実行するGCを信頼します)。
...
関連する部分を太字で強調しています。
YouTubeシリーズのAndroid Performance Patternsをご覧ください。アプリのメモリ使用量を管理するためのヒントが表示されます(sではなくAndroidのArrayMap
sとSparseArray
s を使用するなどHashMap
)。
の後にガベージコレクタを呼び出す必要はありません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.
そのため、ガベージコレクターはエラーを生成する前にメモリを解放しようとしましたが、失敗しました。