2

AndroidのBitmapメモリの問題により、Web からイメージをダウンロードし、ローカル コピーを保存し、必要に応じてローカル コピーから を作成するカスタム ローダーおよびダウンローダー クラスを実装することになりましたBitmap。これらを のリストにSoftReference<T>保持して、しばらく保持し、その後ガベージ コレクションを行い、その時点でクラスのfinalize()メソッドが呼び出されます。

protected void finalize() throws Throwable {
    Log.w("IMAGEPACK", "Finalizing " + mBitmap);
    if(mBitmap!=null&&!mBitmap.isRecycled()) mBitmap.recycle();
    super.finalize();
}

LogCat を見ると、このコードはクラッシュの直前に発生していると判断しました。私もコードをステップ実行しましたが、失敗したのはこの行です。

私は以前に同期参照カウントを使用するソリューションを持っていましたが、これはかなり信頼できるように見えましたが、これを回避したい前に手動で記述された参照カウントに大きな問題がありました。元に戻さなければならないかもしれませんが、ここでビットマップのリサイクルが失敗する理由を知りたいです。

現在、2.3.3 の Samsung Galaxy S でテストしています。

4

1 に答える 1

0

recycle()be への参照を失った場合、実際に呼び出す必要はありませんBitmapBitmapクラスはすでにメモリをオーバーライドして割り当てを解除しているため、finalize()あなたがしていることは冗長です。

また、ドキュメント自体によると:

これは高度な呼び出しであり、通常、このビットマップへの参照がなくなると通常の GC プロセスによってこのメモリが解放されるため、呼び出す必要はありません。

ビットマップがもう必要ない場合はリサイクルが存在しますが、なんらかの理由で参照を保持する必要があります (保持したい追加のメタデータで Bitmap オブジェクトをオーバーロードしている可能性があります)。Bitmap オブジェクトへの参照を保持しているだけの場合は、それを逆参照するだけで十分です。

于 2012-10-12T17:10:51.190 に答える