资讯专栏INFORMATION COLUMN

MemoryAnalyzer补充

zhunjiee / 1245人阅读

摘要:如果说一个对象已经不被任何程序逻辑所需要但是还存在被根元素引用的情况,我们可以说这里存在内存泄露。图内存消耗聚集对象信息在这张图上,我们可以清楚的看到,这个对象集合中保存了大量对象的引用,就是它导致的内存泄露。

首先,之前在网上下载的是Myeclipse的插件 --memory analyzer,在网站的下面是Memory Analyzer的单机版,单机版安装简单,适合日常操作。下载地址:http://www.eclipse.org/mat/do...
之前一直纠结如何获取一个Java项目的内存分析的hprof文件,网上找了很多博客都是一笔带过(这个很容易?!),最后可能是搜索恰当,用JVM指令:

jmap -dump:format=b,file=文件名.hprof[pid]

导出内存信息文件,然后利用Memory Analyzer工具打开进行内存分析(对于内存泄露,OOM等分析有很大的帮助)。

分析三步曲

通常我们都会采用下面的“三步曲”来分析内存泄露问题:

首先,对问题发生时刻的系统内存状态获取一个整体印象。

第二步,找到最有可能导致内存泄露的元凶,通常也就是消耗内存最多的对象

接下来,进一步去查看这个内存消耗大户的具体情况,看看是否有什么异常的行为

下面将用一个基本的例子来展示如何采用“三步曲”来查看生产的分析报告。

查看报告之一:内存消耗的整体状况

图 7. 内存泄露分析报告

如图 7 所示,在报告上最醒目的就是一张简洁明了的饼图,从图上我们可以清晰地看到一个可疑对象消耗了系统 99% 的内存。在图的下方还有对这个可疑对象的进一步描述。我们可以看到内存是由java.util.Vectorcom.ibm.oti.vm.BootstrapClassLoader 负责这个对象的加载。这段描述非常短,但我相信您已经可以从中找到很多线索了,比如是哪个类占用了绝大多数的内存,它属于哪个组件等等。
接下来,我们应该进一步去分析问题,为什么一个 Vector 会占据了系统 99% 的内存,谁阻止了垃圾回收机制对它的回收。

查看报告之二:分析问题的所在

首先我们简单回顾下 JAVA 的内存回收机制,内存空间中垃圾回收的工作由垃圾回收器 (Garbage Collector,GC) 完成的,它的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。
在垃圾回收机制中有一组元素被称为根元素集合,它们是一组被虚拟机直接引用的对象,比如,正在运行的线程对象,系统调用栈里面的对象以及被 system class loader 所加载的那些对象。堆空间中的每个对象都是由一个根元素为起点被层层调用的。因此,一个对象还被某一个存活的根元素所引用,就会被认为是存活对象,不能被回收,进行内存释放。因此,我们可以通过分析一个对象到根元素的引用路径来分析为什么该对象不能被顺利回收。如果说一个对象已经不被任何程序逻辑所需要但是还存在被根元素引用的情况,我们可以说这里存在内存泄露。
现在,让我们开始真正的寻找内存泄露之旅,点击“Details ”链接,可以看到如图 8 所示对可疑对象 1 的详细分析报告。
图 8. 可疑对象 1 的详细分析报告

我们查看下从 GC 根元素到内存消耗聚集点的最短路径:
图 9. 从根元素到内存消耗聚集点的最短路径

我们可以很清楚的看到整个引用链,内存聚集点是一个拥有大量对象的集合,如果你对代码比较熟悉的话,相信这些信息应该能给你提供一些找到内存泄露的思路了。
接下来,我们再继续看看,这个对象集合里到底存放了什么,为什么会消耗掉如此多的内存。
图 10. 内存消耗聚集对象信息

在这张图上,我们可以清楚的看到,这个对象集合中保存了大量 Person 对象的引用,就是它导致的内存泄露。
至此,我们已经拥有了足够的信息去寻找泄露点,回到代码,我们发现,是下面的代码导致了内存泄露 :
清单 1. 内存泄漏的代码段

while (1<2) 
{ 
            
    Person person = new Person("name","address",i); 
    v.add(person); 
    person = null; 
}
总结

从上面的例子我们可以看到用 MAT 来进行堆转储文件分析,寻找内存泄露非常简单,尤其是对于新手而言,这是一个很好的辅助分析工具。但是,MAT 绝对不仅仅是一个“傻瓜式”内存分析工具,它还提供很多高级功能,比如 MAT 支持用 OQL(Object Query Language)heap dump 中的对象进行查询,支持对线程的分析等,有关这些功能的使用可以参考 MAT 的帮助文档。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71414.html

相关文章

  • 关于Myeclipse2017 MemoryAnalyzer的安装

    最近想要安装MemoryAnalyzer(MAT)这个性能分析工具的插件,本以为网上教程那么多,教我一个技术一般的人足够了,我安装的是Myeclipse2017,可是在网上翻了一圈,大多数的Myeclipse教程都是10版本的,我呢,不想在论坛上问(没耐心...),突然想到了自己当初装svn插件时的事情,类比一下是不是也可以呢?步骤如下:首先下载MemoryAnalyzer插件(这个一样)http...

    CompileYouth 评论0 收藏0
  • 如何使用和安装eclipse 的 memory analyzer工具(java内存分析工具)

    摘要:注本人刚接触这东西时,走了很多弯路,并且不知道怎么解决。最后自己瞎搞,搞出来了,在这里给刚接触的人写个简单提示,以免浪费时间,查找解决方案 本文章是写给那些在eclipse上安装了Memory analyzer工具但是确无法正常使用工具的人看的 如果你无法在eclipse上直接使用该工具,那么可以到http://www.eclipse.org/mat/do... 上面下载相对应的 st...

    tunny 评论0 收藏0
  • 性能优化(三)看完这篇文章,至少解决 APP 中 90 % 的内存异常问题

    摘要:不能满足被回收的条件,尽管调用也还是不能得到回收这就造成了内存泄漏。种解决单例中的内存泄漏将引用置为销毁监听使用弱引用将监听器放入弱引用中从弱引用中取出回调通过第七小点就能完美的解决单例中回调引起的内存泄漏。我们为什么要优化内存 showImg(https://user-gold-cdn.xitu.io/2019/5/12/16aac64e31d8c501); 在 Android 中我们写的...

    Elle 评论0 收藏0
  • 一个基于vue和element-ui的树形穿梭框组件

    摘要:在市面上找到一个好用的树形穿梭框组件都很难,又不想仅仅因为一个穿梭框在之外引入其他重量级插件,因此就有了。版本增加穿梭框左侧右侧数据勾选事件,穿梭框左侧右侧底部。 el-tree-transfer 简介·请先阅读文档及版本说明 因为公司业务使用vue框架,ui库使用的element-ui。在市面上找到一个好用的vue树形穿梭框组件都很难,又不想仅仅因为一个穿梭框在element-ui之...

    Corwien 评论0 收藏0

发表评论

0条评论

zhunjiee

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<