Android:OutofMemoryError:位图大小超过VM预算,没有理由我可以看到

Mey*_*ann 34 android gallery out-of-memory ddms imageview

我有一个OutOfMemory异常,画廊超过600x800像素JPEG.


环境

我一直在使用带有大约600x800像素的JPG图像的Gallery.

由于我的内容可能比图像更复杂,我将每个视图设置为一个RelativeLayout,它将JPView包装在ImageView中.

为了"加速"用户体验,我有一个4个插槽的简单缓存,预取(在一个looper中)左边有1个图像,1个图像右边显示图像并将它们保存在4槽HashMap中.

该平台

我使用的是256 RAM和128堆大小的AVD,屏幕为600x800.它也发生在Entourage Edge目标上,除了使用设备它更难调试.


问题

我一直在例外:

OutofMemoryError: bitmap size exceeds VM budget
Run Code Online (Sandbox Code Playgroud)

并且它在获取第五个图像时发生.我试图改变我的图像缓存的大小,它仍然是相同的.


奇怪的是:应该没有内存问题

为了确保堆限制远离我的需要,我在开始时定义了一个虚拟的8MB数组,并将其保留为未引用,以便立即调度.它是活动线程的成员,定义如下

static { @SuppressWarnings("unused")
byte dummy[] = new byte[ 8*1024*1024 ]; }    
Run Code Online (Sandbox Code Playgroud)

结果是堆大小接近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  
Run Code Online (Sandbox Code Playgroud)

并在详细信息表中显示:

Type  Count  Total Size   Smallest   Largest   Median    Average
free  1,536  8.739MB      16B        7.750MB   24B       5.825KB
Run Code Online (Sandbox Code Playgroud)

最大的块是7.7MB.然而LogCat说:

ERROR/dalvikvm-heap(1923): 925200-byte external allocation too large for this process.
Run Code Online (Sandbox Code Playgroud)

如果你介意中位数和平均值之间的关系,可以假设大多数可用的块非常小.但是,有一个块足够大的位图,它是7.7M.怎么还不够呢?

注意:我记录了一个堆跟踪.在查看分配的数据量时,感觉不会超过2M.它确实与DDMS的可用内存报告相匹配.


  • 可能是我遇到像堆碎片这样的问题?
  • 如何解决/解决问题?
  • 堆是否共享给所有线程?
  • 可能是我以错误的方式解释DDMS读数,并且实际上没有900K块可以分配?如果是这样,有人可以告诉我在哪里可以看到吗?

非常感谢

Meymann

Fed*_*dor 12

我觉得你的情况没什么特别之处.内存不足.内存中不能有多个600x800位图,它们会消耗太多内存.您应该将它们保存到SD并按需加载到内存.我认为这正是你所做的.

您应该注意的一件事是:DDMS显示Java堆内存消耗.但是,DDMS中也没有显示本机内存.据我所知,位图是在本机内存中创建的.所以DDMS只是一个跟踪这些内存问题的糟糕工具.您只需要确保释放内存,垃圾收集器不再需要后会收集这些图像.

垃圾收集器按照自己的计划工作.这就是你应该在你不再需要的位图上调用Bitmap.recycle()方法的原因.此方法可以释放您用完的本机内存.这样您就不依赖GC了,您可以尽快释放最大的内存.

首先,您应确保不泄漏位图.

这是一篇关于内存分配的好帖子,它可以帮助你深入挖掘

  • 当您使用4槽缓存时,可以在从此缓存中删除旧图像时调用recycle(). (3认同)

Fed*_*dor 5

不确定它是否适合您,但是您是否尝试过将图像加载到Bitmap对象时对图像奇怪的内存问题