Android MAT 工具使用

本文介绍了MAT的基本概念,包括GCRoot、内存泄漏、不同类型的引用、ShallowHeap与RetainedHeap的区别,以及如何利用MAT工具进行内存分析,如利用Histogram、DominatorTree、Path to GC Roots等功能,还详细介绍了OQL查询语言的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MAT 基本概念

前言

上个月在公司给雏鹰上的一节课,这是分享纪要,感觉自己博客里面内容少的可怜,拿过来凑数。。哈哈哈~~

1.1 GC Root

基本思想:以”GC Roots”的对象作为起始点向下搜索,搜索形成的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(即不可达的),则该对象被判定为可以被回收的对象,反之不能被回收。

1.2 内存泄漏

对象无用了,但仍然可达(未释放),垃圾回收器无法回收。

1.3 强(strong)、软(soft)、弱(weak)、虚(phantom)引用

Phantom reference
和soft,weak Reference区别较大,它的get()方法总是返回null。这意味着你只能用PhantomReference本身,而得不到它指向的对象。当WeakReference指向的对象变得弱可达(weakly reachable)时会立即被放到ReferenceQueue中,这在finalization、garbage collection之前发生。理论上,你可以在finalize()方法中使对象“复活”(使一个强引用指向它就行了,gc不会回收它)。但没法复活PhantomReference指向的对象。而PhantomReference是在garbage collection之后被放到ReferenceQueue中的,没法复活。
关于Phantom reference的更多讨论,请参考:understanding-weak-references

2.1 Shallow Heap

Shallow size就是对象本身占用内存的大小,不包含其引用的对象内存,实际分析中作用不大。在堆上,看起来是一堆原生的byte[], char[], int[],对象本身的内存都很小。所以我们可以看到以Shallow Heap进行排序的Histogram图中,排在第一位第二位的是byte,char

2.2 Retained Heap

retained heap值的计算方式是将retained set中的所有对象大小叠加。或者说,由于X被释放,导致其它所有被释放对象(包括被递归释放的)所占的heap大小。
Retained Set 当X被回收时那些将被GC回收的对象集合。

比如: 一个ArrayList持有100,000个对象,每一个占用16 bytes,移除这些ArrayList可以释放16 x 100,000 + X,X代表ArrayList的shallow大小。相对于shallow heap,RetainedHeap可以更精确的反映一个对象实际占用的大小(因为如果该对象释放,retained heap都可以被释放)。

2.3 Histogram(直方图)

可列出每一个类的实例数。支持正则表达式查找,也可以计算出该类所有对象的retained size
这里写图片描述

2.4 Dominator Tree (支配树)

Dominator Tree:对象之间dominator关系树。如果从GC Root到达Y的的所有path都经过X,那么我们称X dominates Y,或者X是Y的Dominator Dominator Tree由系统中复杂的对象图计算而来。从MAT的dominator tree中可以看到占用内存最大的对象以及每个对象的dominator。 我们也可以右键选择Immediate Dominator”来查看某个对象的dominator。

2.5 Path to GC Roots

选择exclude all phantom/weak/soft etc.references, 意思是查看排除虚引用/弱引用/软引用等的引用链
List objects with (以Dominator Tree的方式查看)
incoming references 引用到该对象的对象
outcoming references 被该对象引用的对象
Show objects by class (以class的方式查看)
incoming references 引用到该对象的对象
outcoming references 被该对象引用的对象
这里写图片描述

###2.6 OQL(Object Query Language)
类似SQL查询语言 Classes:Table Objects:Rows Fileds: Cols
查找size=0并且未使用过的ArrayList
select * from java.util.ArrayList where size=0 and modCount=0
查找所有的Activity select * from instanceof android.app.Activity

2.7 内存快照对比

这里写图片描述

二、集合查看使用率使用

1.筛选目标对象
2、Show Retained Set(查找当X被回收时那些将被GC回收的对象集合)
3、筛选指定的Object(Hash Map,ArrayList)并按照大小进行分组(.HashMap.)

这里写图片描述

4.查看指定类的Immediate dominators

5、Collections fill ratio 集合填充率

6. Map Collision Ratio

这里写图片描述

检测每一个HashMap或者HashTable实例并按照碰撞率排序 碰撞率 = 碰撞的实体/Hash表中所有实体
当Hash集合中过多的对象返回相同Hash值的时候,会严重影响性能(Hash算法原理自行搜索),这里来查找导致Hash集合的碰撞率较高的罪魁祸首

HashEntries
通过查看key value

4、通过OQL查询empty并且未修改过的集合:

select * from java.util.ArrayList where size=0 and modCount=0 类似的
select * from java.util.HashMap where size=0 and modCount=0
select * from java.util.Hashtable where count=0 and modCount=0

三、通过GIMP工具查看内存图片,定位问题

1、将图片保存为xxx.data文件,如图
这里写图片描述

2、获取图片的宽高属性
这里写图片描述

3、用GIMP打开保存的文件,输入图片的宽高,然后打开即可查看
这里写图片描述

其实还有更加简单的方法那就是。。。。。
下载最新版的Android Studio ,在他里面分析内存.hprof文件可以直接看图片。是不是很牛逼,赶紧换吧,少年们~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值