Android性能优化第(三)篇---MAT比Menmery Monitor更强大
![]()
在Android性能优化第(一)篇---基本概念中讲了JAVA的四大引用,讲了一下GCRoot,第二篇Memory Monitor检测内存泄露仅仅说了Menmery Monitor的使用,这篇博客谈一下MAT来寻找内存泄露,相对来说,Memory Monitor没有MAT强大,但是在开始介绍MAT之前,上两篇没有说清楚的问题先说一下。
- GC回收对可回收对象的判定
什么样的对象是可以被回收的?
当然是GC发现通过任何referencechain(引用链)无法访问某个对象的时候,该对象即被回收。名词GC
Roots正是分析这一过程的起点,例如JVM自己确保了对象的可到达性(那么JVM就是GC
Roots),所以GCRoots就是这样在内存中保持对象可到达性的,一旦不可到达,即被回收。通常GC Roots是一个在current
thread(当前线程)的call stack(调用栈)上的对象(例如方法参数和局部变量),或者是线程自身或者是system class
loader(系统类加载器)加载的类以及native code(本地代码)保留的活动对象。所以GC
Roots是分析对象为何还存活于内存中的利器。
上面这段话,也写出了检测内存泄露的基本思想:以”GC Roots”的对象作为起始点向下搜索,搜索形成的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(即不可达的),则该对象被判定为可以被回收的对象,反之不能被回收。也写出了内存泄露的原因:对象无用了,但仍然可达(未释放),垃圾回收器无法回收。
好啦,下面开始介绍MAT,MAT工具全称为Memory Analyzer Tool,(MAT下载:http://eclipse.org/mat/downloads.php)是一款详细分析Java堆内存的工具,该工具非常强大,为了使用该工具,我们需要hprof文件。但是该文件不能直接被MAT使用,需要进行一步转化,可以使用hprof-conv命令来转化,但是AndroidStudio可以直接转化。
然後用MAT打开我们导出的文件,我导出了两个文件,test1.hprof和test2.hprof,其中test1.hprof是内存未泄露时的快照,test2.hprof是内存已经泄露的快照。我们用MAT的Histogram(直方图)和Dominator
Tree (支配树)来分析内存情况。Histogram可以列出内存中每个对象的名字、数量以及大小。Dominator
Tree会将所有内存中的对象按大小进行排序,并且我们可以分析对象之间的引用结构。
一、 Histogram(直方图)
可列出每一个类的实例数。支持正则表达式查找,也可以计算出该类所有对象的retained size。默认是通过class(group by class)分类展示的。
这就是test2.hprof的直方图。现在要说两个名词解释。Shallow Heap/Retained Heap
- Shallow Heap
Shallow
size就是对象本身占用内存的大小,不包含其引用的对象内存,实际分析中作用不大。在堆上,看起来是一堆原生的byte[], char[],
int[],对象本身的内存都很小。所以我们可以看到以Shallow
Heap进行排序的Histogram图中,排在第一位第二位的是byte,char - Retained Heap
Retained size是该对象自己的shallow
size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained
size是该对象被GC之后所能回收到内存的总和。RetainedHeap可以更精确的反映一个对象实际占用的大小(因为如果该对象释放,retained
heap都可以被释放)。
Histogram中是可以显示对象的数量的,那么比如说我们现在怀疑MainActivity中有可能存在内存泄漏,就可以在第一行的正则表达式框中搜索“MainActivity”,如下所示:
可以看到MainActivity的数量是2,这不正常,解决这个,就需要查看MainActivity被谁引用了,不能被释放。我们右键选择exclude
all phantom/weak/soft etc.references, 意思是查看排除虚引用/弱引用/软引用等的引用链
(这些引用最终都能够被GC干掉,所以排除)
还有其他菜单供选择
- List objects with (以Dominator Tree的方式查看)
- incoming references 引用到该对象的对象
- outcoming references 被该对象引用的对象
- Show objects by class (以class的方式查看)
- incoming references 引用到该对象的对象
- outcoming references 被该对象引用的对象
当你按上面操作之后,凶手就出现了,原来是UserManger的实例。
还有可以通过包名来查看Histogram。
还有更强大的,通过OQL语句查询,有点像写SQL语句。
是不是分分钟查出MainActivity有两个对象。哈哈!
比如:查找size=0并且未使用过的ArrayList
select * from java.util.ArrayList where size=0 and modCount=0
这个地方可以多研究研究。
二、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。它可以将所有对象按照Heap大小排序显示, 这样大内存对象就是排在前几名的,我们可以搜索大内存对象通向GC Roots的路径,因为内存占用越高的对象越值得怀疑,使用方法跟Histogram(直方图)差不多,在这里我就不做过多的介绍了。
三、内存快照对比
我们可以将test1.hprof的直方图与test2.hprof的直方图对比来看,其中Object#0是test1.hprof的,Object#1是test2.hprof的,通过比较看哪一些对象的大小相差过大。
其他资料:
官方的帮助文档
http://wiki.eclipse.org/index.php/MemoryAnalyzer
使用 Eclipse Memory Analyzer 进行堆转储文件分析
http://www.vogella.de/articles/EclipseMemoryAnalyser/article.html
MAT使用教程
http://www.vogella.de/articles/EclipseMemoryAnalyser/article.html
Android性能优化第(三)篇---MAT比Menmery Monitor更强大的更多相关文章
- Android内存优化9 内存检测工具3 MAT比Menmery Monitor更强大
在Android性能优化第(一)篇---基本概念中讲了JAVA的四大引用,讲了一下GCRoot,第二篇Memory Monitor检测内存泄露仅仅说了Menmery Monitor的使用,这篇博客谈一 ...
- Android性能优化系列总篇
目前性能优化专题已完成以下部分: 性能优化总纲——性能问题及性能调优方式 性能优化第四篇——移动网络优化 性能优化第三篇——Java(Android)代码优化 性能优化第二篇——布局优化 性能优化第一 ...
- Android性能优化之内存篇
下面是内存篇章的学习笔记,部分内容与前面的性能优化典范有重合,欢迎大家一起学习交流! 1)Memory, GC, and Performance 众所周知,与C/C++需要通过手动编码来申请以及释放内 ...
- Android性能优化之渲染篇
下面是渲染篇章的学习笔记,部分内容和前面的性能优化典范有重合,欢迎大家一起学习交流! 1)Why Rendering Performance Matters 现在有不少App为了达到很华丽的视觉效果, ...
- 【转载】Android性能优化之渲染篇
下面是渲染篇章的学习笔记,欢迎大家一起学习交流! 1)Why Rendering Performance Matters 现在有不少App为了达到很华丽的视觉效果,会需要在界面上层叠很多的视图组件,但 ...
- Android性能优化之运算篇
下面是运算篇章的学习笔记,部分内容与前面的性能优化典范有重合,欢迎大家一起学习交流! 1)Intro to Compute and Memory Problems Android中的Java代码会需要 ...
- Android性能优化问题总结
性能优化这块,分为UI性能优化.内存优化.数据库优化.网络优化.耗电优化等等.可以从1.如何发现问题,2.怎么解决问题,3.解决效果对比,这几个方面去描述.举个简单例子——UI优化,可以从 UI出现什 ...
- Android性能优化的方方面面
通常项目比较大的APP都面临着如下性能问题,APP启动慢.界面跳转慢.事件相应慢.滑动和动画卡顿.展现内容慢等,有的公司处理的很好,有的还有很大的优化空间,对于性能优化,怎么去做,我总结了一下性能优化 ...
- Android 性能优化的方面方面都在这儿
又到周六了,鸿洋的不定期的周六放送又来了~~这次来谈谈性能优化吧.大家在工作中或多或少都会拿自家的应用和竞品app做比对,不可避免的需要做一些app性能优化的活.很多时候可能是策略上的调整,不过还是有 ...
随机推荐
- nsfwjs鉴黄识别最小化案例
3个月前,也就是2月份左右吧,Github上出现一个开源项目: Infinite Red, Inc.工作室宣布开源旗下基于tensorflow的tfjs的鉴黄小工具 据说是从15000张图片中 进行机 ...
- jmeter将上一个请求的结果作为下一个请求的参数——使用正则提取器
转自:http://www.cnblogs.com/0201zcr/p/5089620.html 在压力测试的时候,经常要将几个流程串联起来才能将程序测试通过.如:我现在用户首先要登录,获得我登录的凭 ...
- PostgreSQL drop database 显示会话没有关闭 [已解决]
错误重现 有时候需要删除某个数据库时,会报如下错误,显示有一个连接正在使用数据库,无法删除 ERROR: database "pilot" is being accessed by ...
- WS-*协议栈及相关概念
1. 什么是WS-Security? WS-Security 是一个 SOAP 的扩展,它提供了对 SOAP 消息的认证和加密. 在介绍 WS-Security 之前,我们有必要了解一下 WS-Sec ...
- Codeforces Round #361 (Div. 2) B bfs处理
B. Mike and Shortcuts time limit per test 3 seconds memory limit per test 256 megabytes input standa ...
- 为MYSQL加注释--mysql注释符
上午插入记录的时候一直没有成功,郁闷不知道为什么.因为是很多条记录一起插入,中间一些不用的数据就用"--"来注释了,结果没有效果. 没有办法,在网上找了找,才发现注释符" ...
- Adreno Profiler分析任意安卓游戏特效+抓取资源
听说可以抓去任意游戏特效..保存下,有空研究 AdrenoProfiler 下载地址 Adreno Profiler分析任意安卓游戏特效+抓取资源 教程
- 洛谷 [P1337] 平衡点
模拟退火练手 一道模拟退火的好题 结果一定势能最小 与模拟退火思路高度一致 #include <iostream> #include <cstdio> #include < ...
- linux多线程学习笔记六--一次性初始化和线程私有数据【转】
转自:http://blog.csdn.net/kkxgx/article/details/7513278 版权声明:本文为博主原创文章,未经博主允许不得转载. 一,一次性初始化 以保证线程在调用资源 ...
- 《手把手教你学C语言》学习笔记(3)---变量
编程目的是为了解决问题,编程本质是用计算机的思维操作数据,操作就是算法,数据主要是数据类型,也可以说量,其中分为常量和变量,常量主要是指在量的生命周期内无法改变其值:变量主要是指在量的生命周期内可以随 ...