Android内存泄漏-MAT篇

    最近项目中的内存愈来愈大,因而了解关于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来查看内存泄漏的根本缘由。

  • 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去掉若引用、虚引用、软引用。从而快速获得到这个对象没有释放的根本缘由。

经过对内存的分析,已让我知道程序更容易出现内存泄漏的地方。此为必经之路。

本篇完

相关文章
相关标签/搜索