1

スレッドでビットマップをフェッチし、ビットマップをグローバル メモリ キャッシュに入れるアプリがあります。2.2 エミュレーターでは、十分な数のビットマップ (リストビューにある) を読み込んだ後、再現可能なメモリ不足エラーが発生します。

FATAL EXCEPTION: pool-1-thread-1
  java.lang.OutOfMemoryError: bitmap size exceeds VM budget
  at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
  ...

ヒープは安定しているように見えます (3.3mb)。また、2.2 OS ではビットマップ メモリが別の場所に格納されていると思うので、メモリの量が増えているのがわからないのだろうか? hprof ダンプを実行し、MAT でそれらを表示し続けると、オブジェクト カウントは期待どおりに見えます。

ICS 電話でアプリを実行しても、同じ問題は発生しません (ただし、メモリが増えているだけかもしれません)。後のOSでは、ビットマップメモリ​​をヒープの一部として保持していると思いますか?

どちらの場合でも、アプリによって割り当てられた Bitmap インスタンスを確認する方法はありますか? hprof ダンプは、システム全体の合計数を示しているだけだと思います。しかし、それらがどこから割り当てられたのかわかりません。

私は使用しています:

android.support.v4.util.LruCache<String, Bitmap> 

memcache として - エントリが削除された後、ビットマップ データがクリーンアップされていないように見えます (キャッシュの上限を 5 MB に設定しました)。ビットマップに recycle() のようなメソッドがあったことを覚えていますが、適切にクリーンアップされていないのでしょうか?

ありがとう

4

2 に答える 2

1

ヒープは安定しているように見えます (3.3mb)。また、2.2 OS ではビットマップ メモリが個別に格納されていると思うので、メモリの量が増えているのがわからないのだろうか? hprof ダンプを実行し、MAT でそれらを表示し続けると、オブジェクト カウントは期待どおりに見えます。

2.x では、ビットマップが MAT で使用しているメモリを確認できません (ICS デバイスからダンプを実行すると、突然大きなジャンプが発生する可能性があります)。ただし、使用可能なメモリの量は同じです (デバイスによって異なりますが、一般的には 16 MB から 32 MB の間です)。解決策は、メモリ内のビットマップをできるだけ少なくすることです。サムネイルのサイズしかない場合は、メモリに保持することで問題を解決できるかもしれませんが、一般的にはそれほど多くをロードすることはできません。

于 2012-04-22T16:44:47.620 に答える
1

それ以降のバージョンでは、ビットマップ データがネイティブ ヒープに保持されます。しかし、それでもこのデータはビットマップの予算に反してカウントされます。このエラーを回避するには、recycle! を呼び出す必要があります。そのため、LruCache を拡張し、そこでオーバーライドentryRemovedして recycle を呼び出します。さらに、デバイスのメモリに応じてキャッシュに制限を加えます。たとえば、使用できますActivityManager.getMemoryClass()

    ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    int memoryClass = activityManager.getMemoryClass();

memoryClassdalvik ヒープがメガバイト単位で含まれています。たとえば、その値の 1/5 をキャッシュの制限として使用できます。

それでも、ビットマップ メモリはファイナライザーでのみ解放されるため、これでは OOM エラーを回避するには不十分な場合があります。ビットマップ処理に関する公式ドキュメントを必ず読んでください。すべてが失敗した場合でも、電話System.gc()entryRemovedてみて、それが役立つかどうかを確認できます. しかし、Ewoks が指摘したように、これは悪い習慣であるだけでなく、UI スレッドがしばらくの間停止する可能性があるため、これは最後の手段としてのみ行ってください。

于 2012-04-22T16:47:01.830 に答える