我是靠谱客的博主 动听鼠标,最近开发中收集的这篇文章主要介绍分析android程序的内存 mat,Android内存泄漏-MAT篇,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近项目中的内存越来越大,于是了解关于Android内存分析相关的知识,用以解决实际问题。现在有很多好的内存分析工具比如:LeakCanary、DDMS、mat。

一、首先简单介绍下LeakCanary:

在build.gradle文件中添加

f859151f01dca90f4da94d104ee4f9a5.png

在应用的application onCreate方法中添加LeakCanary.install(this),如下

eabdedaec857945e9aeaf7fd9ecfce5d.png

应用运行起来后,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中得如下结果:

dcbb2dc6ffd3d30aaddadcb1ce057a8c.png深色区域的3.6MB、9.3MB、9.6MB标示有内存泄漏的

0e816edb7113b86fb013e47f898b55f2.png

mat的菜单从左到右Overview、Histogram、Dominator_tree、QQL等

1、我们先来看Histogram视图

3acb1c71ea4a518a2224d45319b55aeb.png

这里简单介绍下

b160e26021b84440c07f7a45b05677d2.png

状态栏的意思class Name很简单,Objects标示该对象出现的次数,Shallow Heap标示对象本身所占的内存空间,Retained Heap标示对象本身及其直接饮用或间接引用一起所占的内存空间。一般来说若Shallow Heap和Retained Heap的差距很大就需要仔细分析该对象是不是产生了泄漏,因为它若释放了那么与它直接或间接关联的对象很多都有可能(只能说可能会释放,也许还会有其他地方产生了此对象的引用)释放。

可以看到

d3603fa007c5cf2a52f7473d96ba42a4.png

d26aecc50664bd33b43f1f90c2241b18.png

shallow heap和Retained head差距很大,并且对于Android来说一般TextView、LinearLayout的对象用过之后就会释放,这里还存在这么多。应该是某些activity没有被销毁导致的。故下面对TextView来分析:

996ad9120d9321a7e64533fdde61d10a.png

Path To GC Roots -> exclude all phantim/weak/soft etc. references:查看这个对象的GC Root,不包含虚、弱引用、软引用,剩下的就是强引用。从GC上说,除了强引用外,其他的引用在JVM需要的情况下是都可以 被GC掉的,如果一个对象始终无法被GC,就是因为强引用的存在,从而导致在GC的过程中一直得不到回收,因此就内存溢出了。可以得到如下:

08836348e3a7b22fcd5caf4e42c5def3.png

展开第一个查看

d7bc86725124f44fb9b76aca99e74193.png查看代码得到AudioManager是单例类它的mInstance对象持有AudioRecordButton的引用,AudioRecordButton的对象又持有AskDetail的引用,故而导致activity AskDetail没有释放导致内存泄漏。  此处修改在OnDestory中注销AudioRecordButton的监听器。ps:在Android代码中这种类似监听器的观察者模式用的非常多,最好在destory的时候都要反注入,防止对象保有activity的引用导致activity不能释放。

mAudioRecordBtn.setAudioFinishRecorderListener(null);

mAudioRecordBtn = null;

2、QQL查询

81f48d40b4505e911e996ab861057f33.png

若你怀疑某个类有内存泄漏,则可以直接通过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去掉若引用、虚引用、软引用。从而快速得到到这个对象没有释放的根本原因。

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

本篇完

最后

以上就是动听鼠标为你收集整理的分析android程序的内存 mat,Android内存泄漏-MAT篇的全部内容,希望文章能够帮你解决分析android程序的内存 mat,Android内存泄漏-MAT篇所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部