原文出处:郭霖,http://blog.csdn.net/sinyu890807/article/details/42238633?locationNum=4

Eclipse Memory Analyzer(MAT)是一款内存分析工具,下载地址

这个工具分为Eclipse插件版和独立版两种,如果你是使用Eclipse开发的,那么可以使用插件版MAT,非常方便。如果你是使用Android Studio开发的,那么就只能使用独立版的MAT了

下载好了之后下面我们开始学习如何去分析内存泄露的原因,首先还是进入到DDMS界面,然后在左侧面板选中我们要观察的应用程序进程,接着点击Dump HPROF file按钮,如下图所示:

点击这个按钮之后需要等待一段时间,然后会生成一个HPROF文件,这个文件记录着我们应用程序内部的所有数据。但是目前MAT还是无法打开这个文件的,我们还需要将这个HPROF文件从Dalvik格式转换成J2SE格式,使用hprof-conv命令就可以完成转换工作,如下所示:

hprof-conv dump.hprof converted-dump.hprof  
  • 1

hprof-conv命令文件存放于/platform-tools目录下面。另外如果你是使用的插件版的MAT,也可以直接在Eclipse中打开生成的HPROF文件,不用经过格式转换这一步。

好的,接下来我们就可以来尝试使用MAT工具去分析内存泄漏的原因了,这里需要提醒大家的是,MAT并不会准确地告诉我们哪里发生了内存泄漏,而是会提供一大堆的数据和线索,我们需要自己去分析这些数据来去判断到底是不是真的发生了内存泄漏。那么现在运行MAT工具,然后选择打开转换过后的converted-dump.hprof文件,如下图所示:

MAT中提供了非常多的功能,这里我们只要学习几个最常用的就可以了。上图最中央的那个饼状图展示了最大的几个对象所占内存的比例,这张图中提供的内容并不多,我们可以忽略它。在这个饼状图的下方就有几个非常有用的工具了,我们来学习一下。

Histogram可以列出内存中每个对象的名字、数量以及大小。 
Dominator Tree会将所有内存中的对象按大小进行排序,并且我们可以分析对象之间的引用结构。

一般最常用的就是以上两个功能了,那么我们先从Dominator Tree开始学起。

现在点击Dominator Tree,结果如下图所示:

这张图包含的信息非常多,我来带着大家一起解析一下。首先Retained Heap表示这个对象以及它所持有的其它引用(包括直接和间接)所占的总内存,因此从上图中看,前两行的Retained Heap是最大的,我们分析内存泄漏时,内存最大的对象也是最应该去怀疑的。

另外大家应该可以注意到,在每一行的最左边都有一个文件型的图标,这些图标有的左下角带有一个红色的点,有的则没有。带有红点的对象就表示是可以被GC Roots访问到的,根据上面的讲解,可以被GC Root访问到的对象都是无法被回收的。那么这就说明所有带红色的对象都是泄漏的对象吗?当然不是,因为有些对象系统需要一直使用,本来就不应该被回收。我们可以注意到,上图当中所有带红点的对象最右边都有写一个System Class,说明这是一个由系统管理的对象,并不是由我们自己创建并导致内存泄漏的对象。

那么上图中就无法看出内存泄漏的原因了吗?确实,内存泄漏本来就不是这么容易找出的,我们还需要进一步进行分析。上图当中,除了带有System Class的行之外,最大的就是第二行的Bitmap对象了,虽然Bitmap对象现在不能被GC Roots访问到,但不代表着Bitmap所持有的其它引用也不会被GC Roots访问到。现在我们可以对着第二行点击右键 -> Path to GC Roots -> exclude weak references,为什么选择exclude weak references呢?因为弱引用是不会阻止对象被垃圾回收器回收的,所以我们这里直接把它排除掉,结果如下图所示:

可以看到,Bitmap对象经过层层引用之后,到了MainActivity$LeakClass这个对象,然后在图标的左下角有个红色的图标,就说明在这里可以被GC Roots访问到了,并且这是由我们自己创建的Thread,并不是System Class了,那么由于MainActivity$LeakClass能被GC Roots访问到导致不能被回收,导致它所持有的其它引用也无法被回收了,包括MainActivity,也包括MainActivity中所包含的图片。

通过这种方式,我们就成功地将内存泄漏的原因找出来了。这是Dominator Tree中比较常用的一种分析方式,即搜索大内存对象通向GC Roots的路径,因为内存占用越高的对象越值得怀疑。

接下来我们再来学习一下Histogram的用法,回到Overview界面,点击Histogram,结果如下图所示:

这里是把当前应用程序中所有的对象的名字、数量和大小全部都列出来了,需要注意的是,这里的对象都是只有Shallow Heap而没有Retained Heap的,那么Shallow Heap又是什么意思呢?就是当前对象自己所占内存的大小,不包含引用关系的,比如说上图当中,byte[]对象的Shallow Heap最高,说明我们应用程序中用了很多byte[]类型的数据,比如说图片。可以通过右键 -> List objects -> with incoming references来查看具体是谁在使用这些byte[]。

那么通过Histogram又怎么去分析内存泄漏的原因呢?当然其实也可以用和Dominator Tree中比较相似的方式,即分析大内存的对象,比如上图中byte[]对象内存占用很高,我们通过分析byte[],最终也是能找到内存泄漏所在的,但是这里我准备使用另外一种更适合Histogram的方式。大家可以看到,Histogram中是可以显示对象的数量的,那么比如说我们现在怀疑MainActivity中有可能存在内存泄漏,就可以在第一行的正则表达式框中搜索“MainActivity”,如下所示:

可以看到,这里将包含“MainActivity”字样的所有对象全部列出了出来,其中第一行就是MainActivity的实例。但是大家有没有注意到,当前内存中是有11个MainActivity的实例的,这太不正常了,通过情况下一个Activity应该只有一个实例才对。其实这些对象就是由于我们刚才不断地横竖屏切换所产生的,因为横竖屏切换一次,Activity就会经历一个重新创建的过程,但是由于LeakClass的存在,之前的Activity又无法被系统回收,那么就出现这种一个Activity存在多个实例的情况了。

接下来对着MainActivity右键 -> List objects -> with incoming references查看具体MainActivity实例,如下图所示:

如果想要查看内存泄漏的具体原因,可以对着任意一个MainActivity的实例右键 -> Path to GC Roots -> exclude weak references,结果如下图所示:

可以看到,我们再次找到了内存泄漏的原因,是因为MainActivity$LeakClass对象所导致的。

好了,这大概就是MAT工具最常用的一些用法了,当然这里还要提醒大家一句,工具是死的,人是活的,MAT也没有办法保证一定可以将内存泄漏的原因找出来,还是需要我们对程序的代码有足够多的了解,知道有哪些对象是存活的,以及它们存活的原因,然后再结合MAT给出的数据来进行具体的分析,这样才有可能把一些隐藏得很深的问题原因给找出来。

Eclipse Memory Analyzer 的使用教程最实用相关推荐

  1. Eclipse Memory Analyzer(MAT) 使用总结

    前言 在日常的开发工作中,遇到生产环境报OOM的问题时,你首先会想到采用哪些方式并使用什么样的工具对OOM问题进行分析,定位和解决呢? 实际现场环境无非有这么两种,第一种,如果项目所在的生产服务器不允 ...

  2. 一次使用 Eclipse Memory Analyzer 分析 Tomcat 内存溢出

    最近,线上生产系统突然频繁的 JVM 内存报警!但本系统近期内并没有上线改动! 为了能查清内存报警的原因,使用 Eclipse Memory Analyzer tool(MAT)对 JVM Dump ...

  3. 内存映像分析工具Eclipse Memory Analyzer

    1. Eclipse Memory Analyzer安装 Help ->Eclipse Marketplace,搜索Memory,点击install,->confirm->同意证书内 ...

  4. 一次使用Eclipse Memory Analyzer分析weblogic内存溢出

    前言 在平时开发.测试过程中.甚至是生产环境中,有时会遇到OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题.我们需要找造成OutOfMemoryError原因.一般有两种情况 ...

  5. Eclipse Memory Analyzer 的使用

    原文出处:郭霖,http://blog.csdn.net/sinyu890807/article/details/42238633?locationNum=4 Eclipse Memory Analy ...

  6. 使用 Eclipse Memory Analyzer 进行堆转储文件分析

    概述 对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现.JVM 能够记录 ...

  7. Eclipse Memory Analyzer以及内存泄露的原因

    Eclipse Memory Analyzer是一个非常棒的堆内存分析工具,是JDK自带的堆分析工具jhat的一个非常好的替代品,能够快速地定位Java内存泄露的原因.       可能有的同学会问, ...

  8. solr analyzer_查看您的Solr缓存大小:Eclipse Memory Analyzer

    solr analyzer Solr使用不同的缓存来防止请求期间过多的IO访问和计算. 如果索引不是很频繁发生,则可以通过使用这些缓存来获得巨大的性能提升. 根据索引数据的结构和缓存的大小,它们可能会 ...

  9. 查看您的Solr缓存大小:Eclipse Memory Analyzer

    Solr使用不同的缓存来防止请求期间过多的IO访问和计算. 当索引不是很频繁发生时,您可以通过使用这些缓存来获得巨大的性能提升. 根据索引数据的结构和缓存的大小,它们可能会变得很大,并占用堆内存的很大 ...

最新文章

  1. 为什么我们很难看到代码 5 分钟前的样子?
  2. web login do.php,dologin.php
  3. as it exceeds the max of 500KB._IT狂人第一季 | 如何考察员工
  4. 零配置构建工具:parcel
  5. php warning: directive,安装Composer PHP Warning: copy(): SSL operation failed with code
  6. mysql数据库创建表时通过设置什么属性可以设置字段编号自动增加_Mysql数据库创建表样例和解释...
  7. mysql为什么limit没用,MySQL是否可以使用LIMIT语法进行子查询?如果没有,为什么?...
  8. 说一下html5 drag api,HTML5 DragAPI
  9. 常见的股票量化交易软件主要有哪几种类型?
  10. Zynq7000(XC7Z045FF900)硬件开发完整指南
  11. onkeyup+onafterpaste 限制文本框只能输入数字 在thinkPHP框架中某些不触发的现象
  12. 金蝶软件界面文字全部变为乱码解决办法
  13. 聚合架构-晓岩企业架构系列讲座整理(0-19)
  14. Sklearn上机笔记--标准化
  15. Kettle carte部署与运行
  16. 面向面试题的前端学习-js篇(自用,持续完善中)
  17. 2012~2020年期货全品种TICK数据共享更新至2020.7.24
  18. Android ViewFlipper 用例
  19. 数独小项目开篇:DFS解决数独难题
  20. 基于孪生网络的跟踪算法汇总

热门文章

  1. 垃圾回收的主要区域是堆,那方法区会回收吗?
  2. 旧款华为笔记本解锁智慧语音教程
  3. Word中㎡的上标²变成了2该如何处理
  4. 关键词推广怎么做比较好?抖音宣传做关键词推广有哪些好的方法
  5. linux图像编辑,Photoflare:Linux下简单的开源图像编辑器
  6. oracle数据表转换为mysql数据表
  7. 【解决】萤石云接入视频报错视频编码类型非H264
  8. 中文版扩散模型课程:第一单元
  9. JAVA核心知识点之 数据结构:总结概述
  10. 广东民办大学计算机专业,二本考生:12所民办大学的计算机专业实力不错,报考难度较低...