2

Android pre-honeycomb では、ビットマップのデータが VM に保存されないため、ビットマップに異常なメモリ問題が発生します。その結果、GC によって追跡または削除されません。代わりに、 が呼び出されたときに削除さBitmap.recycle()れます (これは のファイナライザーでも自動的に行われますBitmap)。

これにより、画像のキャッシュを行うときにいくつかの問題が発生します。recycle()ビットマップが削除される予定の場合、他の誰かがそれを使用しているかどうかわからないため、単純に呼び出すことはできません。

私が最初に考えたのは、System.gc()各ビットマップをロードする直前に行うことでした。そうすれば、孤立Bitmapした s がファイナライズされ、ネイティブ メモリが解放されることを願っています。しかし、うまくいきません編集:実際には、ある種の作業を行います。それをSystem.gc()移動し、キャッシュ サイズを半分にした後 (圧縮されていないビットマップ データの途方もなく小さい 2 MB のように見えます)、アプリがクラッシュしなくなったようです (これまでのところ)!

次に考えたのは、すべてのアクティビティのメソッドをサブクラス化Bitmapして呼び出すことにより、手動の参照カウントを実装することでした。しかし、私は最終的なのでできません。ReferenceCountedBitmap.decrementCount()onDestroy()Bitmap

私は現在、ビットマップにBitmapManagerを保持WeakReferenceし、次のようなメソッドを持つ を計画しています:

public void using(Bitmap bm);
public void free(Bitmap bm);

参照をカウントします。

これを扱った経験やアドバイスはありますか?あなたが提案する前に、市場の 80% を無視することはできません。

4

1 に答える 1

0

さて、参照ビューを保存するビットマップマネージャーでこれを解決しました。地図のような構造のビットマップ -> ビューのリスト。

ビットマップを呼び出す前にrecycle()、まずビューからのすべての参照を null に設定します (そうしないと、ビットマップ リサイクル例外がスローされます)。

あなたが言うように、手動のガベージ コレクションは、ネイティブ ヒープに割り当てられ、System.gc()このメモリがいつ解放されるかを推測できないため、ハニカムの前のビットマップでは機能しません。

于 2012-11-30T20:27:23.890 に答える