首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Eclipse开发 >

施用 Eclipse Memory Analyzer 进行堆转储文件分析

2012-09-21 
使用 Eclipse Memory Analyzer 进行堆转储文件分析转自IBM DEVELOPER WORKS对于大型 JAVA 应用程序来说,再

使用 Eclipse Memory Analyzer 进行堆转储文件分析

转自IBM DEVELOPER WORKS

对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现。JVM 能够记录下问题发生时系统的部分运行状态,并将其存储在堆转储 (Heap Dump) 文件中,从而为我们分析和诊断问题提供了重要的依据。

通常内存泄露分析被认为是一件很有难度的工作,一般由团队中的资深人士进行。不过,今天我们要介绍的 MAT(Eclipse Memory Analyzer)被认为是一个“傻瓜式“的堆转储文件分析工具,你只需要轻轻点击一下鼠标就可以生成一个专业的分析报告。和其他内存泄露分析工具相比,MAT 的使用非常容易,基本可以实现一键到位,即使是新手也能够很快上手使用。

MAT 的使用是如此容易,你是不是也很有兴趣来亲自感受下呢,那么第一步我们先来安装 MAT。

准备环境和测试数据

我们使用的是 Eclipse Memory Analyzer V0.8,Sun JDK 6

安装 MAT

和其他插件的安装非常类似,MAT 支持两种安装方式,一种是“单机版“的,也就是说用户不必安装 Eclipse IDE 环境,MAT 作为一个独立的 Eclipse RCP 应用运行;另一种是”集成版“的,也就是说 MAT 也可以作为 Eclipse IDE 的一部分,和现有的开发平台集成。

集成版的安装需要借助 Update Manager。

如图 1 所示,首先通过 Help -> Software Updates... 启动软件更新管理向导。


图 1. 安装插件第一步
施用 Eclipse Memory Analyzer 进行堆转储文件分析配置环境参数

安装完成之后,为了更有效率的使用 MAT,我们还需要做一些配置工作。因为通常而言,分析一个堆转储文件需要消耗很多的堆空间,为了保证分析的效率和性能,在有条件的情况下,我们会建议分配给 MAT 尽可能多的内存资源。你可以采用如下两种方式来分配内存更多的内存资源给 MAT。

一种是修改启动参数 MemoryAnalyzer.exe -vmargs -Xmx4g

另一种是编辑文件 MemoryAnalyzer.ini,在里面添加类似信息 -vmargs – Xmx4g。

至此,MAT 就已经成功地安装配置好了,开始进入实战吧。

获得堆转储文件

巧妇难为无米之炊,我们首先需要获得一个堆转储文件。为了方便,本文采用的是 Sun JDK 6。通常来说,只要你设置了如下所示的 JVM 参数:

-XX:+HeapDumpOnOutOfMemoryError

JVM 就会在发生内存泄露时抓拍下当时的内存状态,也就是我们想要的堆转储文件。

如果你不想等到发生崩溃性的错误时才获得堆转储文件,也可以通过设置如下 JVM 参数来按需获取堆转储文件。

-XX:+HeapDumpOnCtrlBreak

除此之外,还有很多的工具,例如回页首

生成分析报告

首先,启动前面安装配置好的 Memory Analyzer tool , 然后选择菜单项 File- Open Heap Dump 来加载需要分析的堆转储文件。文件加载完成后,你可以看到如图 4 所示的界面:


图 4. 概览
施用 Eclipse Memory Analyzer 进行堆转储文件分析回页首

分析三步曲

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

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

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

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

下面将用一个基本的例子来展示如何采用“三步曲”来查看生产的分析报告。

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


图 7. 内存泄露分析报告
施用 Eclipse Memory Analyzer 进行堆转储文件分析查看报告之二:分析问题的所在

首先我们简单回顾下 JAVA 的内存回收机制,内存空间中垃圾回收的工作由垃圾回收器 (Garbage Collector,GC) 完成的,它的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。

在垃圾回收机制中有一组元素被称为根元素集合,它们是一组被虚拟机直接引用的对象,比如,正在运行的线程对象,系统调用栈里面的对象以及被 system class loader 所加载的那些对象。堆空间中的每个对象都是由一个根元素为起点被层层调用的。因此,一个对象还被某一个存活的根元素所引用,就会被认为是存活对象,不能被回收,进行内存释放。因此,我们可以通过分析一个对象到根元素的引用路径来分析为什么该对象不能被顺利回收。如果说一个对象已经不被任何程序逻辑所需要但是还存在被根元素引用的情况,我们可以说这里存在内存泄露。

现在,让我们开始真正的寻找内存泄露之旅,点击“Details ”链接,可以看到如图 8 所示对可疑对象 1 的详细分析报告。


图 8. 可疑对象 1 的详细分析报告
施用 Eclipse Memory Analyzer 进行堆转储文件分析

回页首

总结

从上面的例子我们可以看到用 MAT 来进行堆转储文件分析,寻找内存泄露非常简单,尤其是对于新手而言,这是一个很好的辅助分析工具。但是,MAT 绝对不仅仅是一个“傻瓜式”内存分析工具,它还提供很多高级功能,比如 MAT 支持用 OQL(Object Query Language)对 heap dump 中的对象进行查询,支持对线程的分析等,有关这些功能的使用可以参考 MAT 的帮助文档。

热点排行