0

アプリケーション ヒープの最大サイズに近いサイズのイメージをロードしようとすると、アプリケーションがクラッシュします。画像を初めてロードするときは問題ありません。次に、Bitmap オブジェクトへの参照を削除し、mBitmap.recycle() を呼び出す場所でそのファイナライズを削除します。 //nativeRecycle が呼び出されます。どうやらメモリ使用量は減っているようですが、画像を再度読み込もうとすると OutOfMemory でクラッシュします。興味深いのは、参照を削除したのと同じクラスでリサイクルを呼び出すと、メモリが解放されたように見え、イメージを再度ロードできることです。したがって、基本的に、ビットマップを参照するオブジェクトのファイナライズに mBitmap.recycle() を配置する場合よりも、mBitmap.recycle() を直接呼び出すと、異なる結果が得られます。なぜこれが起こっているのですか?

4

1 に答える 1

1

ヒープの最大サイズを使用している場合は、幸運 (または不運) になっている可能性があります。recycle() を直接呼び出す場合と、ファイナライザーから呼び出す場合では、GC のタイミングと動作が変化し、違いがわかる場合があります。

ビットマップを再割り当てする前に、ファイナライザー (および recycle()) が呼び出されていることは確かですか? ファイナライザーは信頼性が低く、無期限に延期される可能性があります。現在、テスト中に再割り当ての前にファイナライザーが呼び出されていることがわかっている場合でも、これが常に発生するという保証はありません (特に、異なるヒープ状態または将来/異なるバージョンの Dalvik の場合)。

可能であれば、ファイナライザーの外部から recycle() を呼び出すように努めてください。完了したことがわかっている場合は、メソッドを呼び出すだけです。それ以外の場合は、ReferenceQueue ( https://stackoverflow.com/a/10879076/150001 ) の使用を検討してください。

Dalvik を見てからしばらく経ちましたが、VM はネイティブ コードにポインターが残っていないことを確認する必要があったため、ビットマップ バッファーをクリーンアップするのに数回の GC サイクルが必要だったことを覚えているようです。そのため、バッファは期待どおりに解放されない場合があります。

ヒープの断片化が問題を引き起こしている可能性もありますが、mmap() を使用して大きなバッファーが割り当てられ、断片化に寄与しない可能性は十分にあります (これも、Dalvik の現在のバージョンによって異なります)。

于 2013-03-09T19:38:02.530 に答える