Android内存优化9 内存检测工具3 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 Root Tracing算法,对于可回收对象的判定

上面这段话,也写出了检测内存泄露的基本思想以”GC Roots”的对象作为起始点向下搜索,搜索形成的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(即不可达的),则该对象被判定为可以被回收的对象,反之不能被回收。也写出了内存泄露的原因对象无用了,但仍然可达(未释放),垃圾回收器无法回收。

好啦,下面开始介绍MAT,MAT工具全称为Memory Analyzer Tool,(MAT下载:http://eclipse.org/mat/downloads.php)是一款详细分析Java堆内存的工具,该工具非常强大,为了使用该工具,我们需要hprof文件。但是该文件不能直接被MAT使用,需要进行一步转化,可以使用hprof-conv命令来转化,但是AndroidStudio可以直接转化。

导出标准的hprof文件

然後用MAT打开我们导出的文件,我导出了两个文件,test1.hprof和test2.hprof,其中test1.hprof是内存未泄露时的快照,test2.hprof是内存已经泄露的快照。我们用MAT的Histogram(直方图)和Dominator
Tree (支配树)来分析内存情况。Histogram可以列出内存中每个对象的名字、数量以及大小。Dominator
Tree会将所有内存中的对象按大小进行排序,并且我们可以分析对象之间的引用结构。

MAT工具主界面

一、 Histogram(直方图)

可列出每一个类的实例数。支持正则表达式查找,也可以计算出该类所有对象的retained size。默认是通过class(group by class)分类展示的。

直方图.png

这就是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

原文地址:https://www.cnblogs.com/ldq2016/p/8472753.html

时间: 2025-01-21 20:49:37

Android内存优化9 内存检测工具3 MAT比Menmery Monitor更强大的相关文章

Android 性能优化之内存泄漏检测以及内存优化(上)

在 Java 中,内存的分配是由程序完成的,而内存的释放则是由 Garbage Collecation(GC) 完成的,Java/Android 程序员不用像 C/C++ 程序员一样手动调用相关函数来管理内存的分配和释放,虽然方便了很多,但是这也就造成了内存泄漏的可能性,所以记录一下针对 Android 应用的内存泄漏的检测,处理和优化的相关内容,上篇主要会分析 Java/Android 的内存分配以及 GC 的详细分析,中篇会阐述 Android 内存泄漏的检测和内存泄漏的常见产生情景,下篇会

Android应用优化之内存概念

导语 现在的Android智能手机发展信息万变,从一开始的HTC到小米价格战到现在高端市场份额战,在软硬件都发生了翻天覆地的变化.在硬件上内存从一开始的一两百M到现在4G.从软件上我们从一开始为了实现需求而写代码到现在为了代码更健壮.更漂亮而进行不断优化代码.这些都是Android发展的必然一步.今天我来跟大家一起分享Android内存优化的相关概念和实践. 概念 进程内存与RAM之间的关系 进程内存既是虚拟内存(或者叫逻辑内存),而程序的运行需要实实在在的内存,即物理内存(RAM),在需要的时

[Android 性能优化系列]内存之终极篇--降低你的内存消耗

大家如果喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地址:http://developer.android.com/training/articles/memory.html 在接下来的一段时间里,我会每天翻译一部分关于性能提升的Android官方文档给大家 建议大家在看本文之前先去我的博客看看 [Android 性能优化系列]内存之基础篇--Andr

[Android 性能优化系列]内存之基础篇--Android怎样管理内存

大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地址:http://developer.android.com/training/articles/memory.html 在接下来的一段时间里,我会每天翻译一部分关于性能提升的Android官方文档给大家 以下是本次的正文: ################ 随机訪问存储器(Ram) 无论在哪种软件

Android 性能优化 五 性能分析工具dumpsys的使用

Android提供的dumpsys工具可以用于查看感兴趣的系统服务信息与状态,手机连接电脑后可以直接命令行执行adb shell dumpsys 查看所有支持的Service但是这样输出的太多,可以通过dumpsys | grep "DUMP OF SERVICE" 仅显示主要的Service的信息 一.列出dumpsys所有支持命令 > adb shell $ dumpsys | grep "DUMP OF SERVICE" 以下是在我个人三星S3手机上的输

10个工具让你的 shell 脚本更强大

10个工具让你的 shell 脚本更强大 很多人误以为shell脚本只能在命令行下使用.其实shell也可以调用一些GUI组件,例如菜单,警告框,进度条等等.你可以控制最终的输出,光标位 置还有各种输出效果.下面我将介绍一些工具,帮助你创建强大的,互动的,用户友好的 Unix/Linux shell脚本.我在FreeBSD和Linux下测试过这些工具,不过其他UNIX系列的操作系统应该都支持的. 1. notify-send 命令 这个命令可以让你通过通知进程发送一个桌面通知给用户.这可以用来向

Android性能优化之内存篇

http://www.cnblogs.com/flyme2012/p/dd1b11a4ea151458d77411f5e99bc0dc.html 下面是内存篇章的学习笔记,部分内容与前面的性能优化典范有重合,欢迎大家一起学习交流! 1)Memory, GC, and Performance 众所周知,与C/C++需要通过手动编码来申请以及释放内存有所不同,Java拥有GC的机制.Android系统里面有一个Generational Heap Memory的 模型,系统会根据内存中不同的内存数据类

几个C++内存泄漏和越界检测工具简介

一.BoundsChecker    或许你还不知道大名顶顶的Nu-Mega,但一定听说过他们的产品SoftICE,BoundsChecker也是这家公司的产品.与Visual C++配合使用,据说威力强大.本人和没有实际用过,在此复制一下百度百科的简介,好有个简单的认识.    BoundsChecker是一个运行时错误检测工具,它主要定位程序运行时期发生的各种错误.它通过驻留在Visual C++开发环境内部的自动处理调试程序来加速应用程序的开发,缩短产品发布时间.BoundsChecker

Android 如何优化APP内存

极力推荐Android 开发大总结文章:欢迎收藏 程序员Android 力荐 ,Android 开发者需要的必备技能 随机存取存储器(RAM)在任何软件开发环境中都是非常有价值的资源,但对于物理内存经常受到限制的移动操作系统来说,它更有价值. 尽管Android运行时(ART)和Dalvik虚拟机都执行常规垃圾收集,但这并不意味着您可以忽略应用程序分配和释放内存的时间和位置. 您仍然需要避免引入内存泄漏,通常由静态成员变量中的对象引用引起,并在生命周期回调定义的适当时间释放任何引用对象. 本页面