文档详情

安卓内存溢出排查.docx

发布:2017-12-10约2.3千字共5页下载文档
文本预览下载声明
在此记录掌上安卓内存溢出问题的排查过程,希望能抛砖引玉,对大家在后面排查内存溢出问题有一定的帮助。在使用应用时,发现重复的关闭、重启后,系统就会抛出oom异常,那就是有资源在程序关闭时无法得到释放。对于android平台,其托管层使用dalvik jvm,其堆内存具有一定大小,一般最大堆大小为16MB,超过此大小则会抛出oom错误。看到oom错误,就利用ddms里面的内存检测工具update heap来查看其堆内存使用情况,发现每次退出和重新进入程序,data object都会增加0.2MB,反复多次最终导致内存溢出。这应该就是程序退出后,没有清理后续的数据引用。给eclipse安装上MAT。MAT即Eclipse Memory Analyzer(/mat),是一个开源的免费内存分析工具。安装完成后,利用ddms里工具dump hprof file来生成hprof文件。由于其格式与标准的hprof文件不一致,所以需要用到sdk目录下tools的hprof-conv工具来生成格式化的hprof文件。在eclipse里面直接打开,就可以看到很多的变量实例等,看到这么多就不知从何下手了。于是还是利用ddms里面的heap工具,不过这次开始对程序代码进行屏蔽。由于我们程序是分模块的,所以屏蔽起来相对简单。先将最有可能发生泄漏的缓存模块屏蔽,后将图片缓存模块屏蔽,再后将网络请求模块屏蔽,发现都不是。最后将所有的都屏蔽掉,只保留开场屏和主界面(主界面里面的界面元素也被屏蔽掉,相当于只剩一个TabActivity空壳了)。期间修改了开场屏的实现方式,即handler不用post runnable来实现,直接post message,还有主界面的按返回键的处理方式,也取消了无所谓的线程开销。发现目前没有发生内存泄漏问题了。现在开启网络链接请求模块,发现没有发生内存泄漏,再开启广告视图的监听模块,发现发生泄漏了(嗯,找到一个泄漏的地方了)。关闭广告视图的监听模块,继续排查其他模块,发现只有广告视图模块发生了泄漏,其他的模块在data object达到一定的大小后,gc会自动去回收,即data object大小会保持在一个平均值,不会随程序的开关而不断增大。图1 Heap调试 现在可以确定是广告模块出现了泄漏,排查代码,发现ScheduledExecutorService mScheduledExecutorService = null;在程序执行完毕后,并非每次都shutdown并释放资源。暂时不修改代码,先进入程序,生成Heap HPROF File,退出程序重新进入程序,再次生成Heap HPROF File文件,然后将这两个文件转换并开启在eclipse,调出Navigation History视图,对其Histogram右键并Add to Compare Basket,重复打开另一个HPROF文件并加入对比队列,在Compare Basket视图里执行compare the results,在对比结果视图里查找AdSwitcher(广告视图的类),发现其实例多了一个,右键AdSwitcher实例,list objects - with incoming references,即持有此引用的实例,在新视图里右键对象,Path to GC Roots - exclude weak/soft references,即去除弱/软引用,弱软引用GC会自动回收,无须查看。查看下,其依然持有ScheduledThreadPoolExecutor实例。图2 MAT对比视图图3 MAT强引用查找结果 修改代码,在activity执行onDestory时,手动去shutdown并释放当前的ScheduledThreadPoolExecutor,再次用ddms的heap调试,可以自动释放data object,data object可保存在一个均值。至此,整个查找过程结束,提交代码,收工~总结:程序中不经意就会发生内存问题,较容易发生此问题的地方有:1、注册监听却不去注销监听。2、Context的引用。如需必要,可考虑生命周期更长的Application Context。3、启动了却不去管理的线程,很有可能持有context或其他资源导致程序无法释放资源。4、bitmap等图片资源5、AsyncTask等系统组件的合理使用等。其解决方法即,合理利用软/弱/虚引用,对图像进行压缩,动态回收内存,优化jvm堆内存分配及自定义堆内存等方面。查找问题过程中应用到的资源:1、Android_MAT.pdf(/file/d/0B6tt5piUV3RWZGYxZTg1ZjQtY2E0ZS00NzlkLWJjMzUtZTYxYWE4YTVjZmQ2/edit?pli=1)2
显示全部
相似文档