600x800 ピクセルを超える JPEG のギャラリーで OutOfMemory 例外が発生しています。
環境
600x800 ピクセル前後の JPG 画像でギャラリーを使用しています。
私のコンテンツは単なる画像よりも少し複雑かもしれないので、各ビューを ImageView を JPG でラップする RelativeLayout に設定しました。
ユーザーエクスペリエンスを「高速化」するために、表示された画像の左と右に約 1 つの画像を (ルーパーで) プリフェッチし、4 スロットの HashMap に保持する 4 つのスロットの単純なキャッシュがあります。
プラットフォーム
256 RAM と 128 ヒープ サイズの AVD を 600x800 画面で使用しています。Entourage Edge ターゲットでも発生しますが、デバイスではデバッグが難しくなります。
問題
私は例外を受けています:
OutofMemoryError: bitmap size exceeds VM budget
そして、5 番目の画像を取得するときに発生します。画像キャッシュのサイズを変更しようとしましたが、それでも同じです。
奇妙なこと: メモリの問題があってはならない
ヒープ制限が必要なものから大きく離れていることを確認するために、最初にダミーの 8MB 配列を定義し、参照されないようにして、すぐにディスパッチされるようにしました。これはアクティビティ スレッドのメンバーであり、次のように定義されます。
static { @SuppressWarnings("unused")
byte dummy[] = new byte[ 8*1024*1024 ]; }
その結果、ヒープ サイズはほぼ 11 MB になり、すべて空き状態になります。 クラッシュし始めた後にそのトリックを追加したことに注意してください。OutOfMemory の頻度が低くなります。
現在、DDMS を使用しています。クラッシュの直前 (クラッシュ後はあまり変化しません)、DDMS は次のように表示します。
ID Heap Size Allocated Free %Used #Objects
1 11.195 MB 2.428 MB 8.767 MB 21.69% 47,156
詳細テーブルには次のように表示されます。
Type Count Total Size Smallest Largest Median Average
free 1,536 8.739MB 16B 7.750MB 24B 5.825KB
最大ブロックは 7.7MB です。それでも、LogCat は次のように述べています。
ERROR/dalvikvm-heap(1923): 925200-byte external allocation too large for this process.
中央値と平均値の関係が気になる場合は、使用可能なブロックのほとんどが非常に小さいと想定するのが妥当です。ただし、ビットマップには十分な大きさのブロックがあり、7.7M です。それでも足りないのはなぜですか?
注: ヒープ トレースを記録しました。割り当てられたデータの量を見ると、2M 以上割り当てられているようには感じられません。これは、DDMS による空きメモリ レポートと一致します。
- ヒープの断片化などの問題が発生している可能性がありますか?
- 問題を解決/回避するにはどうすればよいですか?
- ヒープはすべてのスレッドで共有されていますか?
- DDMS の読み取り値を間違った方法で解釈した可能性があり、割り当てる 900K ブロックが実際にはありませんか? もしそうなら、誰か私がそれを見ることができる場所を教えてもらえますか?
どうもありがとう
メイマン