Eclipse Memory Analyzer(MAT)使用

Eclipse Memory Analyzer(MAT)使用java

 1、OutOfMemoryError

平时开发、测试过程当中,有时会遇到OutOfMemoryError,Java堆溢出了,这代表程序有严重的问题,咱们须要找出形成OutOfMemoryError缘由。web

通常有两种状况:数组

一、内存泄露,对象已经死了,没法经过垃圾收集器进行自动回收,经过找出泄露的代码位置和缘由,才好肯定解决方案;缓存

二、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的状况。 多线程

以上是处理Java堆问题的思路,具体是怎么进行分析,这里介绍使用Eclipse Memory Analyzer tool(MAT)工具分析的过程。并发

常见OutOfMemoryErroreclipse

java.lang.OutOfMemoryError:Java heap space工具

Java虚拟机堆里面已经没有更多的空间了。你正准备建立一个新的对象,可是这个要建立的对象须要的内存已经超过了虚拟机所剩的了。虚拟机会尝试经过full GC来回收内存,若是不行的话,就会抛出这个信息(能够经过-Xmx参数增长堆的大小来解决),若是不行,仍是要找到出现问题的缘由测试

java.lang.OutOfMemoryError:PermGen spacespa

和第一个现象差很少,不过这里准备分配内存的空间是持久代。一样的,空间已经不够了,(增长了-XX:MaxPermSize这个参数的值,问题一般就解决了)

java.lang.OutOfMemoryError: GC overhead limit exceeded

这个问题有点特殊。这里没有提示说堆仍是持久代有问题,虚拟机只是说程序花在垃圾回收上的时间太多了,却没有什么见效。默认的话,若是98%的时间都花在GC上而且回收了才不到2%的空间的话,虚拟机才会抛这个异常。

以上三种错误覆盖了98%以上的场景

java.lang.OutOfMemoryError: unable to create new nativethread

若是虚拟机正在请求操做系统建立一个本地线程,而操做系统没法建立的时候,你会收到这个报错信息。

java.lang.OutOfMemoryError:nativeGetNewTLA

指当虚拟机不能分配新的线程本地空间(Thread Local Area)的时候错误信息。这个异常只有在jRockit虚拟机时才会碰到。线程本地空间是多线程程序里面为了更有效的进行内存分配而创建的缓存。每个线程都有一份本身的缓存,当这个线程要建立对象的时候,就在这上面分配。若是你有不少线程同时并发,又要建立大量的对象,可能会出现这个问题,这种状况下你能够调整一下-XXtlaSize这个参数

java.lang.OutOfMemoryError:Requested array size exceeds VM limit

当建立一个超过虚拟机容许的大小的数组时,这条错误就会出现

java.lang.OutOfMemoryError:request bytes for . Out of swap space

这个错误是当虚拟机向本地操做系统申请内存失败时抛出的。这个和用完了堆或者持久化中的内存的状况有些不一样。这个错误一般是在程序已经逼近平台限制的时候产生的。这个信息告诉你可能已经用光了物理内存以及虚拟内存了。

2、MAT使用

         一、Mat插件安装

              1)下载Mat ,Mat下载地址:http://www.eclipse.org/mat/

              2)解压下载包:放到eclipse或myeclipse安装目录的dropins目录下

              3)启动eclipse或myeclipse,打开window - > open perspective,看到Memory Analysis证实安装成功

                        也可使用其它方法进行安装,不一一说明

         二、生成dump文件

                   首前制造一条内存泄漏的用例,执行使程序报OutOfMemoryError

                   # ps -ef | grep java

 


                   # jmap -dump:live,format=b,file=mpfile1309

 


         三、使用mat分析

                   启动eclipse或myeclipse,打开file - > Open heap dump,在弹出的对话框选择生成的dump文件(mpfile)打开heapDumps文件,就能够看到MAT给出了overview page

 


结果查看:

1.Histogram能够列出内存中的对象,对象的个数以及大小。
2. Dominator Tree能够列出那个线程,以及线程下面的那些对象占用的空间。
3.Top consumers经过图形列出最大的object。
4.Leak Suspects经过MA自动分析泄漏的缘由。

分析:

Histogram以下图:

Objects:类的对象的数量;

Shallow size:就是对象自己占用内存的大小,不包含对其余对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和;

Retained size:是该对象本身的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained size是该对象被GC以后所能回收到内存的总和。

咱们发现cn.test.TestBean类的对象占用了不少空间。

 


DominatorTree以下图:

 


咱们发现cn.test.TestMain-java.util.arraylist-java.lang.object用了不少空间

Top consumers以下图:

这里显示了内存中最大的对象有哪些,他们对应的类是哪些,类加载器classloader是哪些。

有些时候,咱们在这里就能够看到代码泄露的位置。

 

 

 

 








Leak Suspects以下图:

该图深色区域被怀疑有内存泄漏,深色区域就占了69.1%。后面的描述,告诉咱们怀疑问题出在java.lang.object中。因此,MAT经过简单的报告就说明了问题所在。

 

 



经过Leak Suspects的Problem Suspect 1点击【Details

从详细内容中我明能够明确的查出是cn.test.TestBean类的对象有问题,内存溢出

 

 

以上是经过MAT分析Tomcat应用程序,找到内存泄露的缘由,还有许多不足之处,但愿你们多多指教

 

转自:https://user.qzone.qq.com/731573705/blog/1436389384

相关文章
相关标签/搜索