Tomcat内存优化4.1 内存泄漏——内存分析工具 MAT 的使用

在eclipse安装、使用MAT插件


简介:
Eclipse提供的一个内存分析工具。它是一个功能丰富的 JAVA 堆转储文件分析工具,可以帮助你发现内存漏洞和减少内存消耗。
官网地址:http://www.eclipse.org/mat

安装(如果你使用的是MOTODEV Studio for Android则默认自带了该工具)
你可以选择安装Eclipse提供的原版插件或使用MOTODEV Studio for Android插件

>>1.原版插件
1).启动Eclipse,一次点击Help -> Intall New Software...;
2).点击输入栏右侧小箭头,选择"Galileo"(我的是3.5版,不同版本要找到和自己版本名称对应的);
3).等待列表更新完毕,找到并展开"General Purpose Tools";
4).选中并下载其中的"Memory Analyser (Incubation)"和"Memory Analyser (Charts)"两项。

>>2.MOTODEV Studio for Android插件
1).启动Eclipse,一次点击Help -> Intall New Software...;
2).通过Add新建一个更新(最新地址可在此获得):
Name:MOTODEV Studio for Android Plugin
Location:https://studio-android.motodevupdate.com/android/2.0
3).下载并安装此更新。
*如果主要针对Android开发,建议使用MOTODEV Studio for Android的整合插件,应为它还提供了很多便利的工具,不过如果已经安装了ADT的需要先手动卸载才能安装,具体请参考:作为插件安装 MOTODEV Studio。

使用方式1 —— 带参数运行
具体可参考:Eclipse Memory Analyser (MAT) - Tutorial
归纳的大致步骤:
(1)在Run Conigurations..中的Arguments设置VM argument为:
-XX:+HeapDumpOnOutOfMemoryError
(2)运行你的项目并生成.hprof文件,如果没看到请按F5刷新项目目录,就在根目录下;
(3)双击.hprof文件打开,选择"Leak Suspects Report"

使用方式2 —— 结合Sequoyah监控特定的设备及应用
<该方式需要你安装了Sequoyah或MOTODEV Studio for Android插件>

具体可参考:使用MAT分析应用内存

--------------------------------------------------------
*注意:
解析过大的HeapDump可能会导致Eclipse抛出OutOfMemory的错误:


这时你需要手动调整Eclipse的缓存大小,可参考官网给出的处理方式(原文链接):


>>我的使用情况:
我的机器只能设到512m,而且始终没法解决OutOfMemory的问题,看来对内存有一定要求呐...

但是我下载了RPC版的MAT却是能正常打开的,Eclipse插件版打不开的朋友可以试试该方式:RPC版MAT下载地址
--------------------------------------------------------

打开后的界面如下:


更详细的使用示例请参考以下文章:
http://wiki.eclipse.org/index.php/MemoryAnalyzer
—— 官方的帮助文档

使用 Eclipse Memory Analyzer 进行堆转储文件分析
—— 来自IBM的使用教程

Eclipse Memory Analyser (MAT) - Tutorial
—— 一个浅显易懂的MAT使用教程

使用Memory Analyzer tool(MAT)分析内存泄漏(一)
使用Memory Analyzer tool(MAT)分析内存泄漏(二)
—— 详细地分析了内存泄露的原因,并举例说明,强烈推荐


有关MAT插件的介绍请看:

安装MAT插件的地址是:http://download.eclipse.org/mat/1.1/update-site

当点击下一步的时候出现:

Cannot complete the install because one or more required items could not be found.
Software being installed: Memory Analyzer RCP 1.1.1.201108240735 (org.eclipse.mat.ui.rcp.feature.feature.group 1.1.1.201108240735)
Missing requirement: Memory Analyzer Help 1.1.1.201108240735 (org.eclipse.mat.ui.help 1.1.1.201108240735) requires 'bundle org.eclipse.help.appserver 3.1.200' but it could not be found
Cannot satisfy dependency:
From: Memory Analyzer RCP 1.1.1.201108240735 (org.eclipse.mat.ui.rcp.feature.feature.group 1.1.1.201108240735)
To: org.eclipse.mat.ui.help [1.1.1.201108240735]

将地址改为:http://archive.eclipse.org/mat/1.2/update-site

安装成功!

使用:


在工作中可能会遇到内存溢出这种灾难性的问题,那么程序肯定是存在问题,找出问题至关重要,上一篇文章讲了jmap命令的使用方法,当然用jmap导出的 文件我们也看不懂啊,那就交给memory analyzer(mat)这个工具,让他帮助我们来观察程序的内存分布情况吧。

MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析。下面来看看要怎么做呢,也许对你有用。官方文档:http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html

造成OutOfMemoryError原因一般有2种:

1、内存泄露,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄露的代码位置和原因,才好确定解决方案;
2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的情况。


1.用jmap生成堆信息

Java程序内存分析:使用mat工具分析内存占用

这样在E盘的jmap文件夹里会有一个map.bin的堆信息文件

2.将堆信息导入到mat中分析

Java程序内存分析:使用mat工具分析内存占用


3. 生成分析报告

mat可以为我们生成多个报告:

Java程序内存分析:使用mat工具分析内存占用Java程序内存分析:使用mat工具分析内存占用

Java程序内存分析:使用mat工具分析内存占用Java程序内存分析:使用mat工具分析内存占用

下面来看看生成的这些数据对我们有什么帮助

Java程序内存分析:使用mat工具分析内存占用

从上图可以看到它的大部分功能,在饼图上,你会发现转储的大小和数量的类,对象和类加载器。
正确的下面,饼图给出了一个印象最大的对象转储。移动你的鼠标一片看到对象中的对象的细节检查在左边。下面的Action标签中:

  • Histogram可以列出内存中的对象,对象的个数以及大小。

  • Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。

  • Top consumers通过图形列出最大的object。

  • Leak Suspects通过MA自动分析泄漏的原因。

Histogram

Java程序内存分析:使用mat工具分析内存占用

  • Class Name : 类名称,java类名

  • Objects : 类的对象的数量,这个对象被创建了多少个

  • Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用

  • Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和


一般来说,Shallow Heap堆中的对象是的大小和保留内存大小相同的对象是堆内存的数量时,将释放对象被垃圾收集。
保 留设置一组主要的对象,例如一个特定类的所有对象,或所有对象的一个特定的类装入器装入的类或者只是一群任意对象,是释放的组对象如果所有对象的主要设置 变得难以接近的。保留设置包括这些对象以及所有其他对象只能通过这些对象。保留大小是总堆大小中包含的所有对象的保留。摘自eclipse


关于的详细讲解,建议大家查看Shallow heap & Retained heap,这是个很重要的概念。

Java程序内存分析:使用mat工具分析内存占用

这儿借助工具提供的regex正则搜索一下我们自己的类,排序后看看哪些相对是占用比较大的。

Java程序内存分析:使用mat工具分析内存占用

左边可以看到类的详细使用,比如所属包,父类是谁,所属的类加载器,内存地址,占用大小和回收情况等

Java程序内存分析:使用mat工具分析内存占用

这儿有个工具可以根据自己的需求分组查找,默认根据class分组,类似我们sql里的group by了~~

Java程序内存分析:使用mat工具分析内存占用

这里可以看到上面3个选项,分别生成overview、leak suspects、top components数据,但是这儿生成的不是图表,如果要看图表在Java程序内存分析:使用mat工具分析内存占用(Overview)中的Action标签里点击查看。

这个是Overview中的Heap Dump Overview视图,从工具栏中点开,这是一个全局的内存占用信息

Used heap dump 79.7 MB
Number of objects 1,535,626
Number of classes8,459
Number of class loaders74
Number of GC roots2,722
Formathprof
JVM version
Time格林尼治标准时间+0800上午9时20分37秒
Date2014-7-2
Identifier size32-bit
File pathE:\jmap\map.bin
File length108,102,005
  • Total: 12 entries


然后可以点开SystemProperties和Thread Overview进行查看,我这里就不贴了内容比较多。

Dominator Tree

Java程序内存分析:使用mat工具分析内存占用

我们可以看到ibatis占了较多内存

Top consumers

Java程序内存分析:使用mat工具分析内存占用

这张图展示的是占用内存比较多的对象的分布,下面是具体的一些类和占用。

150945_hmjj_1767531.png

按等级分布的类使用情况,其实也就是按使用次数查看,java.lang.Class被排在第一

151054_d2q1_1767531.png

还有一张图是我们比较关心的,那就是按包名看占用,根据包我们知道哪些公共用的到jar或自己的包占用

Java程序内存分析:使用mat工具分析内存占用

这样就可以看到包和包中哪些类的占用比较高。

Leak Suspects

Java程序内存分析:使用mat工具分析内存占用

这份报告,看到该图深色区域被怀疑有内存泄漏,可以发现整个heap只有79.7M内存,深色区域就占了62%。所以,MAT通过简单的报告就说明了项目是有可疑代码的,具体点开详情来找到类

Java程序内存分析:使用mat工具分析内存占用

Java程序内存分析:使用mat工具分析内存占用

Java程序内存分析:使用mat工具分析内存占用

点击鼠标,在List Objects-> with outgoing references下可以查看该类都引用了什么对象,由此查看是否因为其他对象导致的内存问题。

下面继续查看pool的gc ROOT

如下图所示的上下文菜单中选择 Path To GC Roots -> exclude weak references, 过滤掉弱引用,因为在这里弱引用不是引起问题的关键。

进入查看即可,我这儿的代码没有问题,就不用贴了。

Java程序内存分析:使用mat工具分析内存占用


The classloader/component"org.apache.catalina.loader.WebappClassLoader @ 0xa34cde8"occupies19,052,864 (22.80%)bytes. The memory is accumulated in one instance of"java.util.HashMap$Entry[]"loaded by"".

Keywords
java.util.HashMap$Entry[]
org.apache.catalina.loader.WebappClassLoader @ 0xa34cde8


这段话是在工具中提示的,他告诉我们WebappClassLoader占了19,052,864字节的容量,这是tomcat的类加载器,JDK自带的系统类加载器中占用比较多的是HashMap。这个其实比较正常,大家经常用map作为存储容器。

除了在上一页看到的描述外,还有Shortest Paths To the Accumulation Point和Accumulated Objects部分,这里说明了从GC root到聚集点的最短路径,以及完整的reference chain。观察Accumulated Objects部分,java.util.HashMap的retained heap(size)最大,所以明显类实例都聚集在HashMap中了。

Java程序内存分析:使用mat工具分析内存占用

来看看Accumulated Objects by Class区域,这里能找到被聚集的对象实例的类名。java.util.HashMap类上头条了,被实例化了5573次,从这儿看出这个程序不存在什 么问题,因为这个数字是比较正常的,但是当出问题的时候我们都会看到比较大的自定义类会在前面,而且占用是相当高。

当然,mat这个工具还有很多的用法,这里把我了解的分享给大家,不管如何,最终我们需要得出系统的内存占用,然后对其进行代码或架构,服务器的优化措施!

参考文献:

http://www.eclipse.org/mat/about/screenshots.php

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

来自:http://my.oschina.net/biezhi/blog/286223



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值