MAT分析内存泄漏

来源:互联网 发布:金纺的危害知乎 编辑:程序博客网 时间:2024/04/29 20:22

说明:


最近在公司做项目的时候,遇到一个内存泄漏的问题,由于代码有点多,有些代码又是别人之前写的,待功能开发完成后,以为事情就这么结束了,心
想总于可以休息了,不用加班了,但是在测试的时候,apk用就了就会出来程序崩溃的信息,弹出一个对话框,对就是ANR时弹出的那种对话框。刚开始
并没有注意,心想盒子用久了的正常现象吧,但是还是有点怀疑,比较才用一上午的嘛,后来我仿佛进播放器(我做的是一个回看播放器的功能),然后退出,再进,再退出,发现内存一直增加,并不会减少,按理退出播放器内存应该下降啊,就算我点了AS上的小车(gc回收)内存也没有任何变化,
于是我怀疑是内存泄漏的问题,由于代码比较多,不好定位问题,加上想学习一下MAT这个工具来分析一下内存泄漏。所以就开始的学习之旅。

MAT简介

MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。
使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。

MAT工具的下载

https://eclipse.org/mat/downloads.php

常见的内存使用不当的情况

请参照Android内存泄漏篇,链接:

获取HPROF文件(head dump 堆快照)

DDMS导出

这个文件可以使用DDMS导出,第一步选择需要分析的进程名,第二步点击Dump HPROF file 按钮生成.hprof文件:
这里写图片描述

说明:

选择存储路径保存后就可以得到对应进程的HPROF文件。eclipse插件可以把上面的工作一键完成。只需要点击Dump HPROF file图标,然后MAT插件就会自动转换格式,并且在eclipse中打开分析结果。eclipse中还专门有个Memory Analysis视图 ,得到对应的文件后,如果安装了Eclipse插件,那么切换到Memory Analyzer视图。使用独立安装的,要使用Android SDK自带的的工具(hprof-conv 位置在sdk/platform-tools/hprof-conv)进行转换

hprof-conv xxx.xxx.xxx.hprof xxx.xxx.xxx.hprof

Android Studio导出

这里写图片描述

说明:

导出.hprof文件后,可以用MAT软件直接打开。

MATOverView面板

这里写图片描述

Histogram:以下图示为分析内存泄露过程

这里写图片描述

查看PlayBackPlayer引用情况

这里写图片描述
这里写图片描述
从左边可以看出,定时器对象持有PlayBackActivity对象,当退出PlayBackActivity时,没有移除定时任务,那么就会让定时器对象持有PlayBackActivity对象的引用,导致PlayBackActivity对象无法被回收,当重复进退PlayBackActivity时,PlayBackActivity对象一直增加,就会导致内存一直增加,出现内存泄漏。

关于shallowsize、retained size

Shallow size:
就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。
Retained size:
是该对象自己的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained size是该对象被GC之后所能回收到内存的总和。

通过QQL过滤

这里写图片描述
选择所有是Activity实例的对象:select * from instanceof android.app.Activity
选择具体类对象:select * from com.starcor.ahgx.PlayBackActivity
然后点击!执行查询

Dominator Tree

这里写图片描述

使用MAT比较heap dumps

这里写图片描述
第二步:
这里写图片描述
第三步:
这里写图片描述
如上图,为查找内存泄漏,通常需要两个 Dump结果作对比,打开 Navigator History面板,将两个表的 Histogram结果都添加到 Compare Basket中去

MAT选项介绍

List objects:
With Outgoing References 显示选中对象持有哪些对象.
With Incoming References 显示选中对象被哪些对象持有。[如果一个类有很多不需要的实例,那么可以找到哪些对象持有该对象,让这个对象没法被回收]

Show object by class:
With Outgoing References 显示选中对象持有哪些对象, 这些对象按类合并在一起排序
With Incoming References 显示选中对象被哪些对象持有.这些对象按类合并在一起排序

Path to GC Roots:
With all references 显示选中对象到GC根节点的引用路径,包括所有类型引用.
Exclude weak references 显示选中对象到GC根节点的引用路径,排除了弱引用. [弱引用不会影响GC回收对象]
Exclude soft references 显示选中对象到GC根节点的引用路径,排除软引用(【译者注】软引用持有的对象在内存空间足够时,GC不回收,内存空间足够时,GC回收)
Exclude phantom references 显示选中对象到GC根节点的引用路径,排除虚引用(【译者注】虚引用是最弱的引用,get()总是返回null,当它的对象被GC回收时,GC将reference放在ReferenceQueue中,用户代码当发现这个reference在在ReferenceQueue时就知道它持有的对象已经被回收了,这时可以做一些清理工作。《Java编程思想》第四版,中文版,第87页写到Java的finilize方法是为了对象被回收前做清理工作,但是事实上会有隐患,虚引用正是弥补)

Java Basics:
classloader 该对象对应的classloader信息
find String 在这个对象中查询需要的字符串(还不确定,需要再搞下)
group by 根据某个字段统计出现的个数
References Statistics Class Loader Explorer 显示引用和对象的统计信息,列出类加载器,包括定义的类
Customized Retained Set 计算选中对象的保留堆,排除指定的引用
Open in Dominator Tree 对选中对象生成支配树
Show as Histogram 展示任意对象的直方图
Thread Details 显示线程的详细信息和属性
Thread Overview and Stacks 线程堆栈

Java Collections:
Array Fill Ratio 输出数组中,非基本类型、非null对象个数占数组总长度的比例。
Arrays Grouped by Size 显示数组的直方图,按大小分组
Collection Fill Ratio 输出给定集合中,非基本类型、非null对象个数占集合容量的比例。
Collections Grouped by Size 显示集合的直方图,按大小分组
Extract Hash Set Values 列出指定hash集合中的元素
Extract List Values 列出指定LinkedList,ArrayList或Vector中的元素
Hash Entries 展开显示指定HashMap或Hashtable中的键值对
Map Collision Ratio 输出指定的映射集合的碰撞率
Primitive Arrays With a Constant Value 列出基本数据类型的数组,这些数组是由一个常数填充的。

Leak Identification:
Component Report
Top Consumers 分析可能的内存浪费或者低效使用的组件,并输出最大的那个

参考:

(http://blog.csdn.net/berber78/article/details/47786859/%22%E5%8F%82%E8%80%831%22)

0 0
原创粉丝点击