最近项目中的内存愈来愈大,因而了解关于Android内存分析相关的知识,用以解决实际问题。如今有不少好的内存分析工具好比:LeakCanary、DDMS、mat。java
1、首先简单介绍下LeakCanary:android
在build.gradle文件中添加bash
在应用的application onCreate方法中添加LeakCanary.install(this),以下app
应用运行起来后,LeakCanary会自动去分析当前的内存状态,若是检测到泄漏会发送到通知栏,点击通知栏就能够跳转到具体的泄漏分析页面。eclipse
2、下面重点介绍下DDMS结合mat分析内存泄漏问题。工具
使用mat分析首先要经过eclipse或是Android studio生成hprof文件,而后使用命令cd到Android sdk的目录下:gradle
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中得以下结果:ui
深色区域的3.6MB、9.3MB、9.6MB标示有内存泄漏的this
mat的菜单从左到右Overview、Histogram、Dominator_tree、QQL等插件
一、咱们先来看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;
二、QQL查询
若你怀疑某个类有内存泄漏,则能够直接经过QQL语句查询该类在内存中的状况如上。
三、Dominator_tree视图
将内存中对象按从大到小的顺序排列和Histogram视图同样分析大的对象,能够经过查看对下的List Objects--->with incoming reference/with outgoing reference或者merge shortest path to gc root来查看内存泄漏的根本缘由。
经过对内存的分析,已让我知道程序更容易出现内存泄漏的地方。此为必经之路。
本篇完