性能优化——内存分析工具的使用

本文将介绍比较常用的的内存泄漏检测工具,包括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的使用
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源码中造成该泄漏可疑点的地方,很容易去定位问题.