我的画廊超过 600x800 像素 JPEG 时遇到内存不足异常。
环境
我一直在使用 Gallery 来处理 600x800 像素左右的 JPG 图像。
由于我的内容可能比图像复杂一些,因此我将每个视图设置为使用 JPG 包装 ImageView 的relativelayout。
为了“加速”用户体验,我有一个 4 个插槽的简单缓存,它预取(在循环程序中)显示图像左侧的 1 个图像和右侧的 1 个图像,并将它们保存在 4 个插槽的 HashMap 中。
该平台
我使用 256 RAM 和 128 堆大小的 AVD,屏幕分辨率为 600x800。
它也会发生在 Entourage Edge 目标上,只不过该设备更难调试。
问题
我遇到了一个例外:
OutofMemoryError: bitmap size exceeds VM budget
当获取第五张图像时就会发生这种情况。我尝试更改图像缓存的大小,但它仍然是相同的。
奇怪的是:不应该是内存问题
为了确保堆限制离我需要的很远,我在开始时定义了一个虚拟的 8MB 数组,并且不引用它,以便立即调度它。它是活动线程的成员,定义如下
static { @SuppressWarnings("unused")
byte dummy[] = new byte[ 8*1024*1024 ]; }
结果是堆大小接近11MB,而且都是免费的。Note我在它开始崩溃后添加了这个技巧。它可以减少 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 块可以分配?如果是这样,有人可以告诉我在哪里可以看到吗?
多谢
Meymann