web-dev-qa-db-ja.com

Android:Bitmap recycle()はどのように機能しますか?

次のようなビットマップオブジェクトに画像をロードしたとしましょう

_Bitmap myBitmap = BitmapFactory.decodeFile(myFile);
_

さて、次のような別のビットマップをロードするとどうなりますか

_myBitmap = BitmapFactory.decodeFile(myFile2);
_

最初のmyBitmapはどうなりますか? Garbage Collectedを取得しますか、または別のビットマップをロードする前に手動でガベージコレクションする必要がありますか。 myBitmap.recycle()

また、途中でリサイクルしながら大きな画像を読み込んで次々に表示するより良い方法はありますか?

81
Anuj Tenani

最初のビットマップは、2番目のビットマップをデコードするときに ガベージコレクション ではありません。 Garbage Collector は、決定するたびに後で実行します。メモリをできるだけ早く解放する場合は、2番目のビットマップをデコードする直前にrecycle()を呼び出す必要があります。

本当に大きな画像をロードしたい場合は、リサンプリングする必要があります。以下に例を示します。 ビットマップオブジェクトに画像を読み込む際のメモリ不足の問題

71
Fedor

問題はこれだと思います:Androidのハニカム以前のバージョンでは、実際の生のビットマップデータはVMメモリではなく、ネイティブメモリに格納されます。このネイティブメモリis対応するJava BitmapオブジェクトがGCされたときに解放されます。

ただし、ネイティブメモリが不足してもdalvik GCはトリガーされないため、アプリがJavaメモリをほとんど使用しない可能性があるため、 dalvik GCは呼び出されませんが、ビットマップに大量のネイティブメモリを使用するため、最終的にOOMエラーが発生します。

少なくともそれは私の推測です。ありがたいことにHoneycomb以降では、すべてのビットマップデータがVMに格納されているため、recycle()を使用する必要はまったくありません。 shakes fist)、可能な限りrecycle()を使用する必要があります(非常に手間がかかります)または、代わりにGCを呼び出すこともできます。

21
Timmmm

次の画像を読み込む前にmyBitmap.recycle()を呼び出す必要があります。

MyFileのソースに応じて(たとえば、元のサイズを制御できないものである場合)、単に任意の数値をリサンプリングするのではなく、画像を読み込むときに、画像を表示サイズにスケーリングする必要があります。

if (myBitmap != null) {
    myBitmap.recycle();
    myBitmap = null;
}
Bitmap original = BitmapFactory.decodeFile(myFile);
myBitmap = Bitmap.createScaledBitmap(original, displayWidth, displayHeight, true);
if (original != myBitmap)
    original.recycle();
original = null;

アクティビティの開始時に初期化したstaticでdisplayWidthとdisplayHeightをキャッシュします。

Display display = getWindowManager().getDefaultDisplay();
displayWidth = display.getWidth();
displayHeight = display.getHeight();
21
djunod

ビットマップがメモリにロードされると、実際には2つの部分データによって作成されました。最初の部分にはビットマップに関する情報が含まれ、別の部分にはビットマップのピクセルに関する情報が含まれます(バイト配列で構成されます)。最初の部分はJava使用済みメモリ、2番目の部分はC++使用済みメモリに存在します。お互いのメモリを直接使用できます。Bitmap.recycle()はC++のメモリを解放するために使用します。それを行うと、GCはJavaの部分を収集し、Cのメモリが常に使用されます。

10
Allen

Timmmmは正しかった。

によると http://developer.Android.com/training/displaying-bitmaps/cache-bitmap.html

また、Android 3.0(API Level 11)より前では、ビットマップのバッキングデータは、予測可能な方法でリリースされないネイティブメモリに保存されていました。 、潜在的にアプリケーションがメモリ制限を短時間超えてクラッシュする可能性があります。

8
Jian