猜猜看,另一个Android位图 - OOM问题!Android内存管理:屏幕密度,请求的图像大小和可用堆
背景
虽然压力测试our application它已经注意到,有可能最高时的应用程序的进程的内存分配与被记录在随后的内OutOfMemory
异常持续,大量使用(猴亚军等)后,堆栈跟踪。当选择ViewPager
下的页面时,该应用下载图像(一次约3个)。当应用程序的长度和气息被执行时,可以有280多个图像可供下载。该应用程序使用Picasso by Square来进行图像下载抽象。值得注意的是,我们应用程序的代码中没有任何一点是我们直接操纵位图...我们相信,非常有才华的Square Inc.员工比我们做得更好。
这里是一个图片
的下面曲线图显示了在dalvikvm-heap
日志消息下记录时的堆分配。红点指示用户带来了新鲜组文章到应用程序,以加强工作出色和应力的应用的量...
DALVIKVM heap allocations http://snag.gy/FgsiN.jpg 图1: Nexus之一堆分配;奥姆斯发生在80MB +
调查最新
反对使用Nexus S,的Nexus 4,野火,HTC难以置信和进一步测试设备万千,轶事测试已经示出的存储器管理是足够用DVM GC跟上由应用程序完成的繁重工作。但是,在Galaxy S II,III,IV和HTC One等高端设备中,OOM普遍存在。事实上,如果有足够的工作要做,我想我们所有的设备最终都会出现故障。
问题
显然有屏幕密度之间的进程的存储器分配和图像的数量在给定的大小会关系(该请求的图像尺寸基于关闭的ImageView的大小),导致该应用程序超出堆限制。我即将开始量化这种关系,但希望SO社群关注这个问题,并(a)同意或不同意这种关系是值得的,(b)提供文献说明如何最好地拟定这种关系。
重要的是要注意,如果我们破坏图像质量,我们的OOM全部消失,但是可惜的是UX更差,这就是为什么我们希望通过最有效地利用可用堆来切块。
备注:以下是负责将这些图像加载到已布置视图的代码部分;
picassoInstance.load(entry.getKey())
.resize(imageView.getMeasuredWidth(),
imageView.getMeasuredHeight())
.centerCrop()
.into(imageView);
上面提到的“图像质量的横飞”简单地由若干像“4”除以imageView.getMeasured...
。
毕加索还提供了多少内存用于位图的快照。您尝试加载的图片有多大?他们是全屏吗?即使是拥有大量内存的最佳手机,也会通过加载三张或更多图像而崩溃。你认为你的观点是在调用毕加索之前测量的吗?您也可以尝试使用'fit()'来代替。 – dnkoutso
如果您的应用程序在位图上非常密集,您也可以考虑探索'largeHeap'属性。如果启用,毕加索将相应地调整内存。对我来说,黄金法则就是尽可能多地解码,而不是更多。看起来你正在这样做。我会密切关注你的使用情况。在我已经在多种设备上测试过的毕加索样本应用程序中,我从未得到过OOM异常,看起来高端设备在清理垃圾方面处理得非常好。 – dnkoutso
感谢您的建议@dnkoutso。据我所知,毕加索表现良好;当OOM确实发生时总能恢复。我会让你张贴我的漏洞。不感兴趣;我是否应该明确地关闭毕加索? – OceanLife