2012-01-25 25 views
13

多くのサンプルでは、​​ビットマップでrecycle()と呼ばれ、nullに設定されています。 これはなぜ必要なのですか?ガベージコレクタはビットマップを解放しませんか?Android - ビットマップとメモリ管理?

Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 
bitmap.recycle(); 
bitmap = null; 

答えて

17

クラブに参加する。それはまあまあです。

Androidの前ハニカム版では、ビットマップのメモリが管理されていないメモリから割り当てられていて、あらゆる種類の問題が発生していました。それはまだリリースされていますが、ビットマップオブジェクトの実装のファイナライザからです。つまり、収集するには少なくとも2回のGC通過が必要です。また、何らかの理由でファイナライザが実行に失敗した場合、あなたは画像を取得します。 DDMSはそれを見ず、どちらもマッチしません。

これは変更されており、ビットマップは管理されたバイト配列で実装されています...

3

bitmap.recycle(); bitmaps.Andで使用されるネイティブヒープを解放すると、GCが参照をすばやく収集できるようになります。

+3

@aryaxt:ファイナライザはあなたのために 'recycle()'を実行しますが、自分で呼び出すとメモリーを早く解放するので、ヒープスペースを使い果たしにくくなります。 – CommonsWare

+1

はい....もう一つ注意してください....リサイクルする前にビットマップが使用されていないことを確認する必要があります。そうでなければ、リサイクルされたビットマップを使用しようとすると例外が発生します。 –

+4

また、Android 3.0のビットマップでは、もはやネイティブヒープを使用しません。 –

1

http://developer.android.com/reference/android/graphics/Bitmap.html#recycle%28%29のドキュメントから。


このビットマップに関連付けられたネイティブオブジェクトを解放し、ピクセルデータへの参照をクリアします。これはピクセルデータを同期して解放しません。それは他の参照がない場合にガベージコレクションされるだけです。ビットマップは「死んだ」とマークされます。つまり、getPixels()またはsetPixels()が呼び出された場合に例外をスローし、何も描画しません。この操作は元に戻すことはできませんので、ビットマップをそれ以上使用する必要がない場合にのみ呼び出すようにしてください。これは高度な呼び出しであり、通常は呼び出す必要はありません。通常のGCプロセスでは、このビットマップへの参照がなくなるとこのメモリが解放されるためです。


したがって、電話する必要はないようです。私がこれまで手動でオブジェクトをnullに設定する必要があるのは、静的変数(またはスコープから簡単に外れない変数)を強制的にメモリから外したい場合だけです。たぶん、ビットマップを連続的に割り振っているのであれば、ガベージコレクションを強制する必要があるかもしれませんが、大部分の場合はおそらく必要ないでしょう。

+1

文書によってはうまくいくようですが、ビットマップがOOMを引き起こしたケースは非常に多くあります。そのため、コード内でこの問題に直面した場合は、ビットマップを次のように設定してください。 nullとコードからGCを呼び出す...(はい、これは最適ではないことを知っているし、gcにguranteedされていない)...しかし、これはいくつかのメモリを取り戻す最後の手段だった....また、ビットマップキャッシュにSoftReferencesを使用する –

+0

私は一度に何百ものビットマップをメモリに読み込んだが問題はなかった。私がこれを見ることができる唯一の方法は、現代の携帯電話での問題です。あなたのメモリがビットマップを漏らしているか、ビットマップを素早く割り当てて捨てている場合です。 – onit

+0

http://code.google.com/p/android/issues/detail?id=11089ロマンスの返事をチェック.... –

0

This article from android development docsには、このトピックに関する多くの情報があります。また、複数のビットマップを使用する場合は、キャッシングに関する記事も参照してください。