web-dev-qa-db-ja.com

ビットマップ、Bitmap.recycle()、WeakReferences、およびガベージコレクション

AndroidのAFAIKでは、メモリリークを回避するために、ビットマップオブジェクトをWeakReferencesとして参照することをお勧めします。ビットマップオブジェクトのハード参照が保持されなくなると、ガベージコレクターは自動的にそれを収集します。

さて、私が正しく理解していれば、ビットマップを解放するには、メソッドBitmap.recycle()を常に呼び出す必要があります。これは、ビットマップオブジェクトに特別なメモリ管理があるためだと思います。

あれは正しいですか?

これが当てはまる場合、WeakReferencesを使用するときは、WeakReferencesが解放されたときにBitmap.recycle()が呼び出されないため、メモリリークが発生する必要があります。または、どういうわけか、WeakReferencesはメモリリークを回避するのに十分ですか?

ありがとう

24
Sly

Bitmap.recycleは呼び出されません必須ガベージコレクターは最終的にビットマップを自動的にクリーンアップするため(参照がない限り)。 Androidのビットマップは、VMヒープではなく、ネイティブメモリに作成されるため、VMヒープは実際のビットマップデータを含まないため非常に小さいです。(編集:Android 3.0 +)ビットマップの実際のサイズではなくなりました。 GCの目的で、またアプリがメモリを使いすぎないようにするために、ヒープ使用量に対して引き続きカウントされます。

ただし、ビットマップに関しては、GCは少し不機嫌そうです。すべてのハード参照を削除すると、ビットマップオブジェクトの割り当て/カウントの方法がおかしいためか、(私の場合は)少し長くビットマップにハングアップすることがあります。 Bitmap.recycleは、GCにそのオブジェクトをより迅速に収集させるのに適しているようです。

いずれにせよ、誤ってハード参照を保持しない限り、Bitmap.recycleを呼び出さなければ、leakメモリを呼び出すことはありません。ただし、OutOfMemoryErrorsを呼び出さずに、一度に割り当てすぎるビットマップや大きすぎるビットマップを割り当てようとすると、recycleが発生する可能性があります。

編集:Android 3.0以降、ビットマップはネイティブメモリに割り当てられなくなりました。ビットマップは他のヒープと同様にVMヒープに割り当てられます。 Javaオブジェクト。ただし、recycleを呼び出す必要がないことについて私が言ったことは引き続き適用されます。

50
Victor