本文将介绍比较常用的的内存泄漏检测工具,包括HeapSnapShot、HeapViewer、MAT
一、HeapSnapShot的使用
HeapSnapShot意思是堆快照,通过堆内存的信息来分析内存泄漏的问题。
1、启动HeapSnapShot
2、显示Heap SnapShot面板
点击截图部分的左上角,可以看到有个App heap,点开,里面还有Image heap、Zygote heap,分别代码app堆内存信息、图片堆内存信息、zygote进程的堆内存信息。
A区域:
列举了堆内存中的所有的类,以下是列表中列名:
名称 |
意义 |
Total Count |
内存中该类的对象个数 |
Heap Count |
堆内存中该类的对象个数 |
Sizeof |
物理大小 |
Shallow size |
该对象本身占有内存大小 |
Retained Size |
释放该对象后,节省的内存大小 |
B区域:
当我们点击某个类时,右边就会显示该类的实例化对象,这里会显示多少个实体,以及详细信息。
名称 |
意义 |
depth |
深度 |
Shallow Size |
对象本身内存大小 |
Dominating Size |
管辖的内存大小 |
当你点击某个对象时,将展开对象内部有哪些对象,同时C区域也会显示哪些对象引用了该对象:
C区域:
某对象引用树对象,在这里可以看到其被谁引用了,比如内存泄漏中,可以看出它被谁引用
二、Heap Viewer工具使用
heap viewer能做什么
实时查看app分配的内存大小和空间内存大小
发现memory leaks
heap viewer的使用条件
5.0以上的系统,包括5.0
开发者选项可以用
Heap Viewer启动:
Heap Viewer面板:
按上图的标记顺序按下,我们就能看到内存的具体数据,右边面板中数值在每次GC时发生改变,包括app自动触发或者你你来手动触发
面板中的名词:
Heap Size |
堆栈分配给App的内存大小 |
Allocated |
已分配使用的内存大小 |
Free |
空闲的内存大小 |
%Used |
Allocated/Heap Size,使用率 |
Objects |
对象数量 |
类型 |
意义 |
free |
空闲的对象 |
data object |
数据对象,类类型对象,最主要的观察对象 |
class object |
类类型的引用对象 |
1-byte array(byte[],boolean[]) |
一个字节的数组对象 |
2-byte array(short[],char[]) |
两个字节的数组对象 |
4-byte array(long[],double[]) |
4个字节的数组对象 |
non-Java object |
非Java对象 |
下面是每一个对象都有的列名含义:
列名 |
意义 |
Count |
数量 |
Total Size |
总共占用的内存大小 |
Smallest |
将对象占用内存的大小从小往大排,排在第一个的对象占用内存大小 |
Largest |
将对象占用内存的大小从小往大排,排在最后一个的对象占用的内存大小 |
Median |
将对象占用内存的大小从小往大排,拍在中间的对象占用的内存大小 |
Average |
平均值 |
当我们点击某一行时,可以看到如下的柱状图:
横坐标是对象的内存大小,这些值随着不同对象是不同的,纵坐标是在某个内存大小上的对象的数量
HeapViewer的使用
那么如何使用Heap Viewer发现内存泄漏呢
HeapViewer中的数值会自动在每次发生GC时会自动更新,那么我们是等着它GC吗?既然我们是来看内存泄漏,那么我们在需要检测内存泄漏的用例执行过后,手动GC下,然后观察data object一栏的total size(也可以观察Heap Size/Allocated内存的情况),看看内存是不是回到一个稳定值,多次操作后,只要内存是稳定在某个值,那么说明诶有内存泄漏,如果都在增长,不管快慢,都是存在内存泄漏的可能性。
Heap Viewer
不光可以用来检测是否有内存泄漏,对于内存抖动,我们也可以用该工具检测,因为内存抖动的时候,会频繁发生
GC
,这个时候我们只需要开启
Heap Viewer,
观察数据的变化,如果发生内存抖动,会观察到数据在段时间内频繁更新
三、MAT的使用
下载:
http://www.eclipse.org/mat/downloads.php
MAT工具全称为Memory Analyzer Tool,一款详细分析Java堆内存的工具,该工具非常强大,为了使用该工具,我们需要hprof文件,但是该文件不能直接被MAT使用,需要进行进一步转化,可以使用hprof-conv命令来转化,但是Android Studio可以直接转化,转化方法如下:
1.
选择一个
hprof
文件,点击右键选择
Export to standard .hprof
选项。
2.
填写更改后的文件名和路径
:
点击
OK
按钮后,
MAT
工具所需的文件就生成了,下面我们用
MAT
来打开该工具
:
1、打开MAT后选择File->Open File选择我们刚生成的hprof文件
2、选择该文件后,MAT会在几秒钟的时间解析该文件,有的hprof文件可能过大,会有更长时间解析,解析后,展现在我们面前的界面如下:
这个是总览界面,会大体给出一些分析后初步的结论
OverView视图:
该视图会在首页总结出当前这个Heap Dump占用了多大的内存,其中涉及的类有多少,对象有多少,类加载器,如果没有回收的对象,会有一个连续,可以直接参看(图中的Objects Histogram)
比如该例子中显示了Heap dump占用了41M的内存,5400个类,96700个对象,6个类加载器,然后还有各种分类信息
Biggest Objects By Retained Size
会列举出Retained Size的最大的几个值,你可以将鼠标直接放到饼图中的扇叶上,可以在右侧看出详细信息
图中灰色区域,并不是我们需要关心的,他是除了大内存对象外的其他对象,我们需要关心的就是图中彩色区域,比如图中
2.4M
的对象,我们来看看该对象到底是啥
:
该对象是一个
Bitmap
对象,你如果想知道该对象到底是什么图片,可以使用图片工具
gimp
工具浏览该对象
.
histogram视图:
histogram
视图主要是查看某个类的实例个数,比如我们在检查内存泄漏时候,要判断是否频繁创建了对象,就可以来看对象的个数来看。也可以通过排序看出占用内存大的对象
:
默认是类名形式展示,你也可以选择不同的显示方式,有以下四种方式
:
下面来演示一下
:
Dominator tree
视图:
该视图会以占用总内存的百分比来列举所有实例对象,注意这个地方是对象而不是类了,这个视图是用来发现大内存对象的。这些对象都可以展开查看更详细的信息,可以看到该对象内部包含的对象:
Leaks suspects
视图:
这个视图会展示一些可能的内存泄漏的点,比如上图上图显示有
3
个内存泄漏可疑点,我们以
Problem Suspect 1
为例来理解该报告,首先我们来看该可疑点详细信息
:
上面信息显示
ImageCahe
类的一个实例
0xa50819f8
占用了
14.19%
的内存,具体值为
5147200
字节
(5147200/1024/1024=4.9M),
并存放在
LinkedHashMap
这个集合中,然后我们点击
Details
跳转到更详细的页面
:
这样我们就能找到在我们的
app
源码中造成该泄漏可疑点的地方,很容易去定位问题
.