您的位置:首页 > 编程语言 > Java开发

eclipse/myeclipse使用Memory Analyzer Tool (mat)方法

2015-08-21 10:36 525 查看
http://www.eclipse.org/mat/downloads.php

http://download.eclipse.org/mat/1.5/update-site/

使用方法:

/article/1382122.html

http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/

/content/2772082.html

http://www.oschina.net/question/129540_23220

eclipse myeclipse使用方法:

update site:

mat

http://download.eclipse.org/mat/1.5/update-site/

http://www.tuicool.com/articles/iqm6Jv

生成dump文件,可以直接用 jmap -dump:format=b,file=xxx.bin ${pid}的方式

安装MAT

可以选择eclipse插件的方式安装
http://download.eclipse.org/mat/1.3/update-site/
也可以选择单独MAT程序下载安装
http://www.eclipse.org/mat/downloads.php
使用MAT查内存溢出

生成dump

生成dump文件,可以直接用 jmap -dump:format=b,file=xxx.bin ${pid}的方式

也可以直接用MemoryAnalyzer.exe (MAT)生成,File-》Acquire Heap Dump -》选择要dump的java进程-》finish就可以了



生成完dump后,可以用MAT打开 dump(如果是MAT dump完后会自动进行解析),File-》Open Heap Dump 对dump文件进行解析,最终生成一个Overview视图,这个图是一个概要图,显示了一些统计信息,包括整个size大小,class数量,以及对象 的数量,同时还将生成一个大对象的top图,并线显示大对象占用内存的百分比。

类似:size:2.2MB Classes:3.3k Objects:50.1k ClassLoader:84 Unreachable Objects Histogram



找出溢出源

Histogram视图(截图里柱子那个,边上的是Dominator Tree ):列出每個class产生了多少個实例,以及占有多大内存,所占百分比



可以很容易找出站内存最多的几个类,根据Retained Heap排序,找出前几个。

可以分不同的维度来查看类的Histogram视图,Group by class、Group by superclass、Group by class loader、Group by package

只要有溢出,时间久了,溢出类的实例数量或者其占有的内存会越来越多,排名也就越来越前,通过多次对比不同时间点下的Histogram图对比就能很容易把溢出类找出来。



Dominator Tree(支配树):列出每个对象(Object instance)与其引用关系的树状结构,还包含了占有多大内存,所占百分比

可以很容易的找出占用内存最多的几个对象,根据Percentage(百分比)来排序。

可以分不同维度来查看对象的Dominator Tree视图,Group by class、Group by class loader、Group by package

和Histogram类似,时间久了,通过多次对比也可以把溢出对象找出来,Dominator Tree和Histogram的区别是站的角度不一样,Histogram是站在类的角度上去看,Dominator Tree是站的对象实例的角度上看,Dominator Tree可以更方便的看出其引用关系。



定位溢出的原因

通过Path to GC Roots或者Merge Shortest Paths to GC Roots



通 过Histogram视图或者Dominator Tree视图,找到疑似溢出的对象或者类后,选择Path to GC Roots或者Merge Shortest Paths to GC Roots,这里有很多过滤选项,一般来讲可以选择exclude all plantom/weak/soft etc. references。这样就排除了虚引用、弱引用、以及软引用,剩下的就是强引用。从GC上说,除了强引用外,其他的引用在JVM需要的情况下是都可以 被GC掉的,如果一个对象始终无法被GC,就是因为强引用的存在,从而导致在GC的过程中一直得不到回收,因此就内存溢出了。

接下来就需要直接定位具体的代码,看看如何释放这些不该存在的对象,比如是否被cache住了,还是其他什么原因。

找到原因,清理干净后,再对照之前的操作,看看对象是否还再持续增长,如果不在,那就说明这个溢出点被成功的堵住了。

最后用jstat跟踪一段时间,看看Old和Perm区的内存是否最终稳定在一个范围内,如果长时间稳定在一个范围,那溢出的问题就解决了,如果还再继续增长,那继续用上述方法,看看是否存在其他代码的溢出点,继续找出,将其堵住。



此外通过list objects或show objects by class也可以达到类似的效果,不过没看GC Roots的方式直观,这里就不细说了。

list objects -- with outgoing references : 查看这个对象持有的外部对象引用。

list objects -- with incoming references : 查看这个对象被哪些外部对象引用。

show objects by class -- with outgoing references :查看这个对象类型持有的外部对象引用

show objects by class -- with incoming references :查看这个对象类型被哪些外部对象引用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: