最近项目中的内存越来越大,于是了解关于Android内存分析相关的知识,用以解决实际问题。现在有很多好的内存分析工具比如:LeakCanary、DDMS、mat。
一、首先简单介绍下LeakCanary:
在build.gradle文件中添加
在应用的application onCreate方法中添加LeakCanary.install(this),如下
应用运行起来后,LeakCanary会自动去分析当前的内存状态,如果检测到泄漏会发送到通知栏,点击通知栏就可以跳转到具体的泄漏分析页面。
二、下面重点介绍下DDMS结合mat分析内存泄漏问题。
使用mat分析首先要通过eclipse或是Android studio生成hprof文件,然后使用命令cd到Android sdk的目录下:
cd /usr/local/android/sdk/tools //改成自己的sdk目录
hprof-conv com.scics.huaxi.hprof ff.hprof //转换格式命令
这样就生成可供mat分析的hprof文件。http://www.eclipse.org/mat/ 此处可下载mat,可以下载独立版亦可以下载eclipse插件版,本人下的是独立版本。将我们得到的hprof文件导入mat中得如下结果:
深色区域的3.6MB、9.3MB、9.6MB标示有内存泄漏的
mat的菜单从左到右Overview、Histogram、Dominator_tree、QQL等
1、我们先来看Histogram视图
这里简单介绍下
状态栏的意思class Name很简单,Objects标示该对象出现的次数,Shallow Heap标示对象本身所占的内存空间,Retained Heap标示对象本身及其直接饮用或间接引用一起所占的内存空间。一般来说若Shallow Heap和Retained Heap的差距很大就需要仔细分析该对象是不是产生了泄漏,因为它若释放了那么与它直接或间接关联的对象很多都有可能(只能说可能会释放,也许还会有其他地方产生了此对象的引用)释放。
可以看到
shallow heap和Retained head差距很大,并且对于Android来说一般TextView、LinearLayout的对象用过之后就会释放,这里还存在这么多。应该是某些activity没有被销毁导致的。故下面对TextView来分析:
Path To GC Roots -> exclude all phantim/weak/soft etc. references:查看这个对象的GC Root,不包含虚、弱引用、软引用,剩下的就是强引用。从GC上说,除了强引用外,其他的引用在JVM需要的情况下是都可以 被GC掉的,如果一个对象始终无法被GC,就是因为强引用的存在,从而导致在GC的过程中一直得不到回收,因此就内存溢出了。可以得到如下:
展开第一个查看查看代码得到AudioManager是单例类它的mInstance对象持有AudioRecordButton的引用,AudioRecordButton的对象又持有AskDetail的引用,故而导致activity AskDetail没有释放导致内存泄漏。 此处修改在OnDestory中注销AudioRecordButton的监听器。ps:在Android代码中这种类似监听器的观察者模式用的非常多,最好在destory的时候都要反注入,防止对象保有activity的引用导致activity不能释放。
mAudioRecordBtn.setAudioFinishRecorderListener(null);
mAudioRecordBtn = null;
2、QQL查询
若你怀疑某个类有内存泄漏,则可以直接通过QQL语句查询该类在内存中的情况如上。
3、Dominator_tree视图
将内存中对象按从大到小的顺序排列和Histogram视图一样分析大的对象,可以通过查看对下的List Objects--->with incoming reference/with outgoing reference或者merge shortest path to gc root来查看内存泄漏的根本原因。
- List objects -> with incoming references:查看这个对象持有的外部对象引用
- List objects -> with outgoing references:查看这个对象被哪些外部对象引用
- merge shortest path to gc root -> exclude all phantim/weak/soft etc. references:查看这个对象的gc root去掉若引用、虚引用、软引用。从而快速得到到这个对象没有释放的根本原因。
通过对内存的分析,已让我知道程序更容易出现内存泄漏的地方。此为必经之路。
本篇完
来源:oschina
链接:https://my.oschina.net/u/579493/blog/802295