找到并修复大堆大小的原因

Gli*_*tch 53 android memory-management ddms

我想弄清楚为什么我的应用程序使用了这么多内存.我经常看到它使用15到18MB之间,这远远高于我的预期.我通过DDMS查看了堆大小,看到了这个:

在此输入图像描述

这看起来有点可疑,因为我的应用程序根本不处理大图像.事实上,我的应用程序中drawables的总和大约是250KB.所以我创建了一个堆转储并使用MAT来找到所有这些内存的去向.byte []数组是迄今为止最大的消费者,所以我深入研究并注意到以下内容:

在此输入图像描述

我完全不知道为什么sPreloadedDrawables负责这么高的保留堆大小.我也不知道如何确定根本原因,或者如何"修复"它.

我应该从哪里出发?我的应用程序主要通过不处理图像数据的服务在后台运行.我确实有用户可以选择使用的活动,但同样,他们使用的小型drawable不能解释如此大的堆大小.我还检查了任何令人讨厌的活动泄漏事件等,但没有找到任何.

编辑:我注意到在模拟器中运行时堆大小要大得多.这很令人困惑.:/

cis*_*rns 44

系统将预加载默认系统资源,这与您的应用程序资源无关,例如复选框和单选按钮的标准Drawables.10.5MB确实看起来很大,但是有很多默认系统资源,一旦存储在内存中,图像会更大.预加载并不新鲜,但ICS中的预加载尺寸可能更大.显示密度可能在其中起作用,只需添加更多在ICS中预装的系统Drawable.

目前没有办法减少由此持有的内存 sPreloadedDrawables

遗憾的是,在针对不使用大多数系统Drawables的应用程序(尤其是游戏)生成应用程序进程后,没有办法清除此问题.在这种情况下,虽然大量的预加载资源似乎是ICS的特定版本(或手机端口)的错误.否则通常是少量内存,所以我怀疑是否有必要使用这种机制来减少预装内存的使用.

如果由于此缓存导致内存不足,那么我可能会向Google提交错误报告.

如果您对更多内部细节感兴趣,可以在此处跟踪资源预加载过程.ZygoteInit.preloadResources

  • 是的.没有一个功能可以关闭它 - 它在zygote进程中完成,该进程创建一次,并且所有应用程序进程都从中生成.因此,它加载的资源在所有进程中共享. (4认同)