我的库超过 600x800 像素 JPEG 时出现 OutOfMemory 异常。
环境
我一直在使用带有 600x800 像素左右的 JPG 图像的图库。
由于我的内容可能比图像更复杂一些,因此我将每个视图设置为将 ImageView 与 JPG 包装在一起的 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,而且都是免费的。 请注意,我在它开始崩溃后添加了该技巧。它使 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 块可以分配?如果是这样,有人可以告诉我在哪里可以看到吗?
非常感谢
迈曼