Android 内存优化 查找问题所在

来源:互联网 发布:广州南航信息中心 知乎 编辑:程序博客网 时间:2024/05/18 03:45

内存飙高,居高不下,oom,是Android程序员经常遇到的问题,想要解决内存问题需要先找到内存问题出在哪里。所以内存问题最难的在于找到哪里导致了内存出问题。

使用Android Device Monitor

点击Android studio 功能栏图标,打开Android Device Monitor
这里写图片描述
这里写图片描述

Android Device Monitor 方便的为我们提供了 Update Heap和Dump HPROF file 两个用来分析内存的工具

这里写图片描述

update heap

单击我们自己的App进程后,单击 update heap按钮,右边的面板可能会出现如下图所示的内容,如果不出现单击Cause GC.

这里写图片描述

这里可以实时动态的看到我们app在消耗的内存,如果app在重复做一个动作,data object 一行中的 Total size 一直在飙升,而没有下降的趋势,说明我们重复的动作中新建的对象一直没有被释放,这就是问题的所在了。

Dump HPROF file

当我们一直重复一个动作,达到一定次数后,点击Dump HPROF file按钮,就可以保存当前的内存分配情况。

这里写图片描述

点击Dump HPROF file按钮后会弹出保存的窗口,保存即可。

然后需要用到 sdk/platform-tools/hprof-conv工具来转换hprof文件,使其能够使用Memory Analyzer (MAT)工具分析。

找到hprof-conv,使用终端执行命令就可以。

这里写图片描述

Memory Analyzer (MAT)

MAT需要先安装才可以使用
官网上去下载匹配自己机器的版本就ok了
http://www.eclipse.org/mat/downloads.php

打开MAT,代开文件选择刚才执行命令行输出的HPROF文件

这里写图片描述

这里能看出一个内存使用的大概分布,继续点击Histogram按钮

这里写图片描述

出现具体的使用情况列表

这里写图片描述

搜索自己刚才重复动作时所访问的页面(某一个Activity之类的)

这里写图片描述

绿色框内就很明显能看出来ActivityProductInfo这个类莫名其妙存在了7个,这肯定就是有问题了,如果存在两个可以理解是GC调用的比较慢,还没有立即回收,存在7个就可以想象继续点击下去,一旦heap内存达到64M,程序就会OOM。

选中ActivityProductInfo,然后右键如果所示

这里写图片描述

Activity的对象没有被释放,一般情况下是广播没关闭或者非静态内部类有持有context,导致Activity一直被持有引用而无法释放,然后找找到底是哪个类持有了context,或者是广播没关闭。

这里写图片描述

很明显可以看到是MyHandler这个类持有了Context,导致了Activity一直无法释放,到这里,我们就算找到了问题,剩下就是看看MyHandler,发现MyHandler是非静态内部类,而且是一个消息循环,持有了Context,只要适当的使用removeCallbacksAndMessages,并且把MyHandler =null,就可以解决问题了。

非静态的内部类 可以直接持有外部类的应用 (因为你不需要new外部类可以直接用他的方法、成员) 而要小心非静态内部类的生命周期 不要高于外部类 高于后会导致 外部类不会被释放 如:非静态内部类里面有静态的成员持有当前类的引用 一般这种情况导致的不释放不好找,这方面的java知识看看《Effect JAVA》就可以理解的更完善了。

0 0
原创粉丝点击