Eclipse Memory Analyzer 堆转储文件分析
目录
2
Eclipse Memory Analyzer 堆转储文件分析................................................................................1
1 背景知识 .................................................................................................................................... 2
Java 如何管理内存 ........................................................................................................ 2
1.1.
Java Heap Dump 是什么? ...........................................................................................3
1.2.
mat 介绍 ..................................................................................................................................... 3
2.1. MAT 是什么? .....................................................................................................................3
2.2 为什么使用 MAT?.............................................................................................................4
3 概述 ............................................................................................................................................ 4
4 准备环境和测试数据................................................................................................................ 4
5 安装 MAT.................................................................................................................................... 4
6 配置环境参数 ............................................................................................................................ 6
7 测试类准备................................................................................................................................ 7
8 设置 JVM 参数........................................................................................................................... 7
Windows 平台使用 Mat..............................................................................................................8
9
JAVA 应用配置 JVM 参数,及生成 hprof 文件...........................................................8
9.1
Tomcat 应用配置 JVM 参数,及生成 hprof 文件 .......................................................9
9.2
Jboss 应用配置 JVM 参数,及生成 hprof 文件 .......................................................11
9.3
LINUX 使用 MAT.................................................................................................................... 13
JAVA 应用配置 JVM 参数,及生成 hprof 文件 .................................................... 13
Tomcat 应用配置 JVM 参数,及生成 hprof 文件................................................ 14
Jboss 应用配置 JVM 参数,及生成 hprof 文件 .................................................. 15
使用 mat 进行分析 hprof 文件 ..........................................................................................16
Mat 工具其他功能说明 .......................................................................................................23
Histogram................................................................................................................23
Dominator Tree......................................................................................................24
Path to GC Roots..................................................................................................26
Dominator Tree Grouped by Class Loader......................................................26
其他资料 .............................................................................................................................. 27
12.1
12.2
12.3
12.4
10.1
10.2
10.3
10
11
12
13
1 背景知识
1.1.Java 如何管理内存
Java 的内存管理就是对象的分配和释放问题。在 Java 中,程序员需要通过关键字 new 为每
个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。另外,对象的释
放是由 GC 决定和执行的。在 Java 中,内存的分配是由程序完成的,而内存的释放是有 GC 完成
的,这种收支两条线 的方法确实简化了程序员的工作。但同时,它也加重了 JVM 的工作。这也
是 Java 程序运行速度较慢的原因之一。因为,GC 为了能够正确释放对象,GC 必须监控每一个对
象的运行状态,包括对象的申请、引用、被引用、赋值等,GC 都需要进行监控。
监视对象状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不
再被引用。
为了更好理解 GC 的工作原理,我们可以将对象考虑为有向图的顶点,将引用关系考虑为图
的有向边,有向边从引用者指向被引对象。另外,每个线程对象可以作为一个图的起始顶点,例
如大多程序从 main 进程开始执行,那么该图就是以 main 进程顶点开始的一棵根树。在这个有向
图中,根顶点可达的对象都是有效对象,GC 将不回收这些对象。如果某个对象 (连通子图)与这
个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被 GC
回收。
以下,我们举一个例子说明内存管理。对于程序的每一个时刻,我们都有一个有向图表示
JVM 的内存分配情况
以下右图,就是左边程序运行到第 6 行的示意图。
Java 使用有向图的方式进行内存管理,可以消除引用循环的问题,例如有三个对象,相互
引用,只要它们和根进程不可达的,那么 GC 也是可以回收它们的。这种方式的 优点是管理内
存的精度很高,但是效率较低。另外一种常用的内存管理技术是使用计数器,例如 COM 模型采
用计数器方式管理构件,它与有向图相比,精度行低 (很难处理循环引用的问题),但执行效率
很高。
1.2.Java Heap Dump 是什么?
我们知道 Java Heap 是所有类实例和数组对象分配的一个运行时数据区,其间所有 Java VM
线程在执行期间共享 Heap 中的数据。那么一个 Java heap dump 相当于在一个特殊的时间点上生
成的一个快照,它就像给一个繁忙的数据仓库在给定的时间上来了一个照片,我们通过这张快照
可以识别哪些组件在那快照的那时间点上是可用的。
由于 Java 说明文档并没有提及到 Java heap dump,在各个不同的 JVM 厂商,存在各个对 Java
heap dump 的介绍。 如 IBM JVM 的 Java heap dump 提供的信息大至和 Java Heap 差不多。
Sun 公司提供的信息基本上是 JVM Stack,运行时常量池和 Java Heap 等.
2
mat 介绍
2.1. MAT 是什么?
MAT(Memory Analyzer Tool),首页:http://www.eclipse.org/mat/ 。一个基于 Eclipse 的内存
分析工具,是一个快速、功能丰富的 JAVA heap 分析工具,它可以帮助我们查找内存泄漏和减少
内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,
看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
Eclipse Memory Analyzer(MAT)是著名的跨平台集成开发环境 Eclipse Galileo 版本的 33 个
组成项目中之一,它是一个功能丰富的 JAVA 堆转储文件分析工具,可以帮助你发现内存漏洞和
减少内存消耗。本文主要介绍如何安装配置 Memory Analyzer,并结合一个实例,介绍如何利用
MAT 来进行堆转储文件分析,找到内存泄露的根源。
2.2 为什么使用 MAT?
当服务器应用占用了过多内存的时候,会遇到 OutOfMemoryError。如何快速定位问题呢?
Eclipse MAT 的出现使这个问题变得非常简单。它能够离线分析 dump 的文件数据。
Eclipse MAT 是 SAP 公司贡献的一个工具,可以在 Eclipse 网站下载到它,完全免费的。它可比
Sun 提供的内存镜像分析工具 jhat 要强太多了。
3 概述
对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我们在测试阶
段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中
进行重现。JVM 能够记录下问题发生时系统的部分运行状态,并将其存储在堆转储 (Heap Dump)
文件中,从而为我们分析和诊断问题提供了重要的依据。
通常内存泄露分析被认为是一件很有难度的工作,一般由团队中的资深人士进行。不过,
今天我们要介绍的 MAT(Eclipse Memory Analyzer)被认为是一个“傻瓜式“的堆转储文件分析工
具,你只需要轻轻点击一下鼠标就可以生成一个专业的分析报告。和其他内存泄露分析工具相 比,
MAT 的使用非常容易,基本可以实现一键到位,即使是新手也能够很快上手使用。
MAT 的使用是如此容易,你是不是也很有兴趣来亲自感受下呢,那么第一步我们先来安装
MAT。
4 准备环境和测试数据
我们使用的是 Eclipse Memory Analyzer V1.1,Sun JDK 6
5 安装 MAT
和其他插件的安装非常类似,MAT 支持两种安装方式,一种是“单机版“的,也就是说
用户不必安装 Eclipse IDE 环境,MAT 作为一个独立的 Eclipse RCP 应用运行;另一种是”集
成版“的,也就是说 MAT 也可以作为 Eclipse IDE 的一部分,和现有的开发平台集成。
集成版的安装需要借助 Update Manager。
如图 1 所示,首先通过 Help -> Software Updates... 启动软件更新管理向导。
图 1. 安装插件第一步
选 择 “Available Software“ 然 后 按 如 图 2 所 示 的 方 式 添 加 MAT 的 更 新 地 址
http://download.eclipse.org/mat/1.1/update-site/。
图 2. 安装插件第二步
如图 3 所示,接下来选择你想要安装的 MAT 的功能点,需要注意的是 Memory
Analyzer (Chart) 这个功能是一个可选的安装项目,它主要用来生成相关的报表,不过如果需
要用到这个功能,你还需要额外的安装 BIRT Chart Engine。
图 3. 安装插件第三步
插件安装完毕,你还需要重新启动 Eclipse 的工作平台。
比较而言,单机版的安装方式非常简单,用户只需要下载相应的安装包,然后解压缩即
可运行,这也是被普遍采用的一种安装方式。在下面的例子里,我们使用的也是单机版的
MAT 。 具 体 的 下 载 要 求 和 地 址 可 参 见 其 产 品 下 载 页 面 :
http://www.eclipse.org/mat/downloads.php。
另外,如果你需要用 MAT 来分析 IBM JVM 生成的 dump 文件的话,还需要额外安装
IBM Diagnostic Tool Framework , 具 体 的 下 载 和 安 装 配 置 步 骤 请 参 见 :
http://www.ibm.com/developerworks/java/jdk/tools /dtfj.html
6 配置环境参数
安装完成之后,为了更有效率的使用 MAT,我们还需要做一些配置工作。因为通常而言,
分析一个堆转储文件需要消耗很多的堆空间,为了保证分析的效率和性能,在有条件的情况下,
我们会建议分 配给 MAT 尽可能多的内存资源。你可以采用如下两种方式来分配内存更多的内存
资源给 MAT。
一种是修改启动参数 MemoryAnalyzer.exe -vmargs -Xmx4g
另一种是编辑文件 MemoryAnalyzer.ini,在里面添加类似信息 -vmargs – Xmx4g。
至此,MAT 就已经成功地安装配置好了,开始进入实战吧。
7 测试类准备
Testheapdumponoutofmemoryerrorweb.rar
8 设置 JVM 参数
首先需要设置了如下所示的 JVM 参数:
-XX:+HeapDumpOnOutOfMemoryError
JVM 就会在发生内存泄露时抓拍下当时的内存状态,也就是我们想要的堆转储文件。
如果你不想等到发生崩溃性的错误时才获得堆转储文件,也可以通过设置如下 JVM 参数来按需获取
堆转储文件。
-XX:+HeapDumpOnCtrlBreak
除此之外,还有很多的工具,例如 JMap,JConsole 都可以帮助我们得到一个堆转储文件。本文实例
就是使用 JMap 直接获取了 Eclipse Galileo 进程的堆转储文件。您可以使用如下命令:
JMap -dump:format=b,file=
jmap -dump:format=b,file=HeapDump.hprof /path/to/bin/java core_dump_file
Via Tools:
* Sun (Linux, Solaris; not on Windows) JMap Java 5: jmap -heap:format=b
*
Sun
(Linux,
Solaris;
Windows
see
link)
JMap
Java
6:
jmap.exe
-dump:format=b,file=HeapDump.hprof
* Sun (Linus, Solaris) JMap with Core Dump File: jmap -dump:format=b,file=HeapDump.hprof
/path/to/bin/java core_dump_file
* Sun JConsole: Launch jconsole.exe and invoke operation dumpHeap() on HotSpotDiagnostic
MBean
* SAP JVMMon: Launch jvmmon.exe and call menu for dumping the heap
不过,您需要了解到,不同厂家的 JVM 所生成的堆转储文件在数据存储格式以及数据存储内容上有
很多区别, MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,
例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解
析(您需要安装额外的插件,请参考 相关说明,本文不作详细解释)。
万事俱备,接下来,我们就可以开始体验一键式的堆存储分析功能了。
9
Windows 平台使用 Mat
9.1
JAVA 应用配置 JVM 参数,及生成 hprof 文件
Conigurations..中的 Arguments 设置 VM argument 为:
-XX:+HeapDumpOnOutOfMemoryError
另外一种指定生成文件存储位置:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/xieyun/test/TestHeapDumpOnOutOfMemoryError.hprof
右 键 , Run as Run