Android内存管理:屏幕密度,请求的图像大小和可用堆

时间:2013-10-30 15:28:30

标签: android memory-management picasso

猜猜是什么,另一个Android-Bitmap-OOM问题!

背景

虽然压力测试our application已经注意到,在持续的,大量使用(像猴子赛跑者一样)之后可以最大化应用程序的进程内存分配,并在随后的记录中记录OutOfMemory个例外堆栈跟踪。当选择ViewPager下的页面时,应用程序会下载图像(一次大约3个)。当应用程序的长度和呼吸运行时,可以下载280多个图像。该应用程序使用Picasso by Square进行图像下载抽象。值得注意的是,在我们的应用程序代码中,我们没有直接操作Bitmaps ...我们相信,非常有才华的Square Inc.员工正在做得比我们做得更好。

这是一张图片

下图显示了dalvikvm-heap日志消息下记录的随时间变化的堆分配。红点表示用户将一组新文章带入应用程序,以加强未完成的工作量并对应用程序施加压力......

DALVIKVM heap allocations http://snag.gy/FgsiN.jpg 图1: Nexus One堆分配; OOM发生在80MB +

调查至今

针对Nexus S,Nexus 4,Wildfire,HTC Incredible以及众多其他测试设备,轶事测试表明,内存管理足以让DVM GC“跟上”完成的繁重工作。应用程序。然而,在诸如Galaxy S II,III,IV和HTC One的高端设备上,OOM是普遍的。事实上,如果有足够的工作要做,我会想象我们所有的设备最终都会出现故障。

问题

屏幕密度(我们要求的图像大小基于ImageView的大小),进程内存分配和给定大小的图像数量之间显然存在关系,这将导致应用程序超出其堆限制。我即将开始量化这种关系,但希望SO社区能够关注这个问题,并且(a)同意或不同意这种关系是值得的,以及(b)提供文献,说明如何最好地建立这种关系。

重要的是要注意,如果我们破坏了图像质量,我们的OOM都会消失,但唉,用户体验更差,这就是为什么我们希望通过最有效地利用可用堆来进行切割。


旁注:这是负责将这些图像加载到已经布局的视图中的代码部分;

picassoInstance.load(entry.getKey())
               .resize(imageView.getMeasuredWidth(), 
                       imageView.getMeasuredHeight())
               .centerCrop()
               .into(imageView);

上面提到的“图像质量的潇洒”只是将imageView.getMeasured...除以“4”之类的数字。

2 个答案:

答案 0 :(得分:2)

首先你需要管理内存分配,这是android中的一个大问题,因为位图占用了大量的内存,因为内存分配可以通过以下方式减少

  1. 将所有尺寸巨大的图片放到资源文件夹中,而不是将它们放在drawabable文件夹中。因为可绘制资源需要内存来缓存它们。如果从资源文件夹加载,图像将不会缓存。并且将占用更少的内存。

    1. 研究用于高效内存管理的Lrucache。
    2. 将资源用于支票TinyPNG
    3. 的小格式
    4. 如果您的图像分辨率太大,请尝试将SVG文件用于图像并加载SVG文件而不是图像。检查此SVG FOR ANDROID
  2. 最后我的英语不是很好希望它可以帮助你。

答案 1 :(得分:0)

这篇文章有点旧,但最近我也遇到过这个问题。也许这会帮助别人。 这个庞大的线程概述/什么帮助了我。

- 确保您使用的是Picasso的Singleton实例

- 使用适合()

- 对于大图像或许多图像或在FragmentPager / StatePager中使用时,您应该使用skipmemorycache()和/或largeHeap声明

阅读主题以获取更多提示。在发布此问题时,没有人在picassos github上发布此问题。

https://github.com/square/picasso/issues/305

祝你好运希望这有助于编码。