『MAT讲解』
MAT讲解:
 
【MAT官方文档】
 
ACTIONS:
Histogram: Lists number of instances per class

直方图:列举实例

Dominator Tree: List the biggest objects and what they keep alive.

统治者树列出最大的对象和他们保持活着

Top Consumers: Print the most expensive objects grouped by class and by package.

顶部的消费者:打印最昂贵的对象类和

Duplicate Classes: Detect classes loaded by multiple class loaders.

重复的类检测多个类加载器加载的类

 
REPORTS:
Leak Suspects: includes leak suspects and a system overview

泄漏嫌疑人:包括泄漏嫌疑人系统概述

Top Components: list reports for components bigger than 1 percent of the total heap.

部件:列表报告成分大于百分之1的总的堆

 
Step By Step:
Component Report: Analyze objects which belong to a common root package or class loader.

部分报告:分析对象属于一个共同的根包类加载器

 
Description:
Shortest Paths To the Accumulation Point:
Class Name
Shallow Heap
Retained Heap 
 
Accumulated Objects:
Class Name 
Shallow Heap 
Retained Heap 
Percentage
 

Accumulated Objects by Class:
Label
Number of Objects
Used Heap Size
Retained Heap Size

 
分析三步曲

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

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

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

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

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

图 7. 内存泄露分析报告

如图 7 所示,在报告上最醒目的就是一张简洁明了的饼图,从图上我们可以 清晰地看到一个可疑对象消耗了系统 99% 的内存。

在 图的下方还有对这个可疑对象的进一步描述。我们可以看到内存是由 java.util.Vector 的实例消耗的,com.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 的帮助文档。

 
 
 
 
 
 
 
 
 
 
 
 
 

1、MAT是什么?

    MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁 阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。

   

2.为什么使用MAT?
    当服务器应用占用了过多内存的时候,会遇到OutOfMemoryError。如何快速定位问题呢?Eclipse MAT的出现使这个问题变得非常简单。它能够离线分析dump的文件数据。
    Eclipse MAT是SAP公司贡献的一个工具,可以在Eclipse网站下载到它,完全免费的。它可比Sun提供的内存镜像分析工具jhat要强太多了。
3.
首页:http://www.eclipse.org/mat/
插件更新地址:
http://download.eclipse.org/mat/1.0/update-site/

先调用jdk的工具得到heap使用情况

我安装的是jdk1.6

C:/>java -version

java version "1.6.0_11"

Java(TM) SE Runtime Environment (build 1.6.0_11-b03)

Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)

调用jdk工具jps查看当前的java进程

C:/>jps

3504 Jps

3676 Bootstrap

3496 org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar

调用jmap工具得到信息

C:/>jmap -dump:format=b,file=heap.bin 3676

Dumping heap to C:/heap.bin ...

Heap dump file created

这时,我们的C盘根目录,就生成了heap.bin文件,用eclipse的file---->open打开这个文件,首先是一个启动图:

这里可以选择查看

1、内存泄露报表,自动检查可能存在内存泄露的对象,通过报表展示存活的对象以及为什么他们没有被垃圾收集;

2、对象报表,对可颖对象的分析,如字符串是否定义重了,空的collection、finalizer以及弱引用等。

我这里选择的是查看内存报表,以下是截的简略图:

 

通过报表展示,蛮清楚的,下面还有详细的说明,这里就没有帖图了,有兴趣的可以继续探究。

posted on 2012-03-07 09:56  grass_dcm  阅读(3800)  评论(0编辑  收藏  举报