内存泄漏是比较常见的一种应用程序性能问题,一旦发生,则系统的可用内存和性能持续下降;最终将导致内存不足(OutOfMemory),系统彻底宕掉,不能响应任何请求,其危害相当严重。同时,Java堆(Heap)中大量的对象以及对象间之复杂关系,导致内存泄漏问题的探测和分析均比较困难,采用相应的辅助工具是很必要的。
我使用的比较多的是Memory Dump Diagnostic for Java (MDD4J)和IBM HeapAnalyzer,这两个工具都能支持几乎所有JDK版本所生成的堆转储文件,使用前可以在两者的帮助文件中查看一下支持列表。
先说一下IBM HeapAnalyzer,下载之后首先阅读一下readme,这上面详细写了HeapAnalyzer的使用方法。对于我用的2.6版本(最新为3.8),可以在命令行中输入<Java path>java –Xmx[heapsize] –jar ha26.jar <heapdump file>来启动工具并加载heapdump文件。对于比较大的heapdump,将-Xmx设置一个较大的值(大于heapdump的大小),来避免加载过程中的OOM。对于64位机器上产生的超大heapdump,个人机器上分析就不大可能了。
打开heapdump文件后,我一般点击“Analysis”里的“Tree View”,以树的形式从根节点展示内存对象分配的信息
heapanalysis1
第一行java.lang.ref.Refenrence这个class及它的76个children占用了67%的已用堆大小(31M/46M),它本身仅占用了76bits。双击java.lang.ref.Refenrence,我们可以看到它所引用的两个子节点。其中一个子节点java.lang.ref.Finalizer后的67%指引我们内存泄漏的问题应该在它的引用上。
heapanalysis2
接下去你可以逐级展开,或者右键点击“Locate a leak suspect”,让HeapAnalyzer帮你找到泄漏可能发生的地方。泄漏一般发生在那些拥有“超乎寻常多”的引用(子节点)的class上,正是这些创建后没有释放、累积了成千上百的对象,造成了OutOfMemory。右键中的“Go to the largest drop subtrees”也是以此为原理而设的,它的解释为:
“Search for total size drop” will find a size drop between the total size of a parent and the biggest total size of child of the parent.
因为出现泄漏的点,每个子节点占用的内存空间不大,但是巨大的数量会导致父节点占用的total size很大。不过反过来寻找到的点都是泄漏发生的地方这种说法是不成立的,否则也不需要我们来分析了。
更多细节的内容,可以看这篇PPT
Memory Dump Diagnostic for Java (MDD4J)则是IBM Support Assistant(ISA)里的一个工具,可以在ISA里加载。它的使用方法和HeapAnalyzer类似,不过它会自动列出“可疑泄漏点”供分析。所依据的,是“分析算法查找父对象与子对象之间对象大小的显著变化。这些发生显著变化的父对象可能是基于数组的容器对象,它们包含大量不断增大的子对象。”
具体的使用方法可以参考《WebSphere Application Server 中的内存泄漏检测与分析:第 2 部分:用于泄漏检测与分析的工具和功能》一文中的实际案例。(不过文中的版本应该比较低,现在能下到的2和3版本有些不同,不过不妨碍使用).
Heapdump工具的使用很简单,难点在于找到“内存泄漏的真正原因”,一般需要通过多个heapdump文件的对比才能找到。
比较分析用于对运行内存泄漏应用程序期间(即可用 Java 堆内存流失时)获取的两个内存转储进行分析。在运行泄漏应用程序的早期触发的内存转储被称为基线内存转储,发生泄漏的应用程序运行一段时间(以允许泄漏程度加大)后触发的内存转储被称为主内存转储。在发生了内存泄漏的情况下,主内存转储可能包含大量对象,而这些对象占用的 Java 堆空间量会比基线内存转储大很多。
为了获得更好的分析结果,建议使主内存转储的触发点与基线内存转储的触发点在时间上拉开一定距离,从而使总耗用堆大小在两个触发点之间大幅增长。
如果发现“主内存转储”中的某个对象数量大大大于“基线内存转储”,那么这个对象一般就是发生泄漏的点。但是要避免在appserver刚启动时就做heapdump,否则会把正常需要分配的对象当作泄漏嫌疑点。比如原先运行3天会发生OOM,那么可以:缩小堆大小,让OOM提早发生;在运行4个小时后每隔4小时手动做一次Heapdump直到OOM发生。这些动作也许不适合在生产环境下进行,可以另建测试环境进行。
之前几篇文章中介绍的分析gc log,和本文讲到的分析heapdump,都是脱机分析法。它们的缺陷就是无法找到代码引起的“性能低下”的原因,正如《用HPjtune分析GC日志》里所看到的那样,系统性能很差,但是没有OOM发生,可用堆在每次full gc后还不断减少的现象不能简单怪罪为内存泄漏,毕竟最后都回收下来了,如果手动做heapdump,可能有问题的对象已被回收,无法得到正确的结果。这种情况下要使用诸如Jprofile这样直接附加到JVM上的工具来监测了。
最后附一下手动生成heapdump的方法,免得事到临头在google。
在Linux/AIX环境下
使用Kill -3 pid命令来调用堆转储.
Windows环境下
1. 找到JVM对象名字。
<wsadmin> set objectName [$AdminControl queryNames
WebSphere:type=JVM,process=<servername>,node=<nodename>,*]
2. 对JVM MBean调用generateHeapDump操作。
<wsadmin> $AdminControl invoke $objectName generateHeapDump
如果上述方法是没有生成,那么进行下面的设置。
访问管理控制台
转到“服务器”>“应用程序服务器”> Server1(或者要获取其堆转储的服务器的名称)>“进程定义”>“环境条目”。
单击“新建”。
在“名称”字段中,输入 IBM_HEAPDUMP(默认是开启的)。在“值”字段中,输入 true。
单击“确定”。
重复步骤 3 至 5,但将 IBM_HEAPDUMP_OUTOFMEMORY 设置为 true。
缺省情况下,将在 ~/WebSphere/AppServer/ 目录中创建内存转储(对于 WebSphere Application Server V6.x 而言,缺省目录是:~/WebSphere/AppServer/profiles/default)。要将堆转储目标定向到另一个目录,请转至“环境条目”,单击“新建”,将 IBM_HEAPDUMPDIR 设置为适当的目录(例如 /heapdumps),然后单击“确定”。
单击“保存”,然后在下一个屏幕中再次单击“保存”。
转到“服务器”>“应用程序服务器”> server1(或者要获取其堆转储的服务器的名称)>“进程定义”>“Java 虚拟机”。
选择“详细垃圾回收”。
单击“保存”,然后在下一个屏幕中再次单击“保存”。
重新启动服务器。
打开命令提示符并转至 /WebSphere/AppServer/bin 目录。
通过发出 kill -3 XXXXX 命令来调用堆转储,其中 XXXXX 是进程标识。
如果WebSphere运行在HP-UX上,那么需要
访问管理控制台
转到“服务器”>“应用程序服务器”> Server1(或者要获取其堆转储的服务器的名称)>“进程定义”>“环境条目”。
在“常规参数”中,输入:-Xrunhprof:depth=0,heap=dump,format=a,thread=n,doe=n
缺省情况下,将在 ~/Websphere/AppServer/ 目录中创建内存转储。要将堆转储目标定向到另一个目录,请添加 HProf 参数 file=/heapdumpdir/hprof.txt,其中 heapdumpdir 是适当的目录,而 hprof.txt 是适当的文件名。如果创建了多个内存转储,那么将把每个内存转储追加到同一个 hprof.txt 文件中。
选中“启用详细垃圾回收方式”。
重新启动服务器。
通过发出 kill -3 XXXXX 命令创建堆转储,其中 XXXXX 是进程标识。
除非另有指定,否则将在 ~/WebSphere/AppServer/ 目录中创建 hprof 转储,并且文件名看起来类似于 java.hprof.txt。
关闭应用程序服务器,然后移动 hprof 转储文件。直到正确关闭应用程序服务器之后,hprof 转储文件才完整。
注意:请检查是否每个 hprof 转储都包含 HEAP DUMP BEGIN 和 HEAP DUMP END 这两组标记。如果 hprof 转储的这两组标记不齐全,那么表明该转储不完整且不能用于分析。
转载 http://www.hashei.me/2009/07/heapanalyzer-and-mod4j-introduction.html
分享到:
相关推荐
IBM HeapAnalyzer 最新版本 java内存分析工具,性能调优,内存泄露排除比不可少的工具
IBM HeapAnalyzer是一款强大的内存分析工具,主要用于分析Java应用的堆内存。当应用程序出现内存泄漏时,HeapAnalyzer可以帮助开发者定位导致内存泄漏的对象和它们的引用路径。通过分析heapdump文件(通常由JVM生成...
IBM HeapAnalyzer是一款强大的Java虚拟机(JVM)内存分析工具,专为诊断和解决Java应用程序的内存泄漏问题而设计。这个工具能够帮助开发者深入理解Java应用程序的内存使用情况,从而优化性能并防止由于内存泄漏导致...
IBM HeapAnalyzer是一款强大的Java内存分析工具,主要用于诊断和解决Java应用程序中的内存泄漏问题。这款工具通过对Java堆内存的深入分析,帮助开发者定位那些占用过多内存的对象,从而优化应用性能。在Java开发过程...
HeapAnalyzer是一款Java内存分析工具,由IBM开发,它可以帮助开发者检查和分析Java堆内存的状态,找出可能存在的内存泄漏或者过度占用内存的对象。通过分析heap dump文件,HeapAnalyzer可以展示对象的分布情况,识别...
IBM Java堆内存分析工具——HeapAnalyzer,是一款专为IBM J9 VM设计的强大内存分析工具,它可以帮助开发者深入理解Java应用程序的内存使用情况,检测并解决内存泄漏问题,从而提升应用性能。本文将详细介绍Heap...
HeapAnalyzer456.jar 是一个专门用于分析Java内存溢出的专业工具,它可以帮助开发者深入理解内存的分配、使用和泄漏状况。本篇文章将详细介绍如何使用HeapAnalyzer456.jar来分析Java内存溢出问题。 首先,我们需要...
IBM HeapAnalyzer 是一个功能强大且实用的工具,旨在帮助开发者和测试人员快速检测和解决 Java 堆溢出和内存泄露问题。通过使用 IBM HeapAnalyzer,开发者可以快速地分析 Java 堆转储,检测可能的 Java 堆泄漏,并...
IBM Heap Analyzer是一款强大的内存分析工具,主要用于Java应用程序的性能优化,特别是针对IBM J9 JVM的内存管理和垃圾收集进行深入分析。这款工具可以帮助开发者诊断和解决内存泄漏、过度对象分配以及垃圾收集效率...
IBM的HeapAnalyzer是一款强大的内存分析工具,主要用于诊断Java应用程序中的内存泄漏问题。它能帮助开发者深入理解Java虚拟机(JVM)的堆内存状态,通过分析heap dump文件,找出那些占用内存过大的对象,以及这些...
使用 IBM 性能分析工具 HeapAnalyzer 解决生产环境中的性能问题 性能分析是企业级应用系统软件不可或缺的一部分,对于业务操作的响应时间和并发数的要求非常高。只有经过不断的调整优化,才能达到资源的最大利用率...
IBM开发的强大的内存dump分析工具,,IBM heapAnalyzer是通过分析OOM后的Java heap dump文件的,通过对dump文件的分析找到内存可能泄露的点
IBM HeapAnalyzer分析工具,版本比较稳定。
IBM HeapAnalyzer是一款强大的Java Out-of-Memory (OOM) 分析工具,主要用于诊断和解决Java应用程序在运行时出现的内存问题。IBM开发此工具是为了帮助Java开发者深入理解内存使用情况,定位内存泄漏或不当的内存分配...
IBM® HeapAnalyzer是一款由IBM公司开发的专业内存分析工具,它主要针对Java应用程序,用于诊断和解决内存泄露问题。HeapAnalyzer通过深入分析Java堆内存的使用情况,帮助开发者找到那些占用内存过大的对象,从而...
IBM内存分析工具,作为一个专业的Java内存诊断工具,专门针对Java内存溢出(Memory Overflow)和内存泄露(Memory Leak)问题进行深度分析,帮助开发者定位并解决这些问题。本文将详细介绍IBM内存分析工具的功能、...
IBM出的一款内存分析工具,可以用来分析websphere生成的内存转储phd格式文件 使用方法: java -jar -Xmx3000m ha456.jar heapdump.20141113.171336.1693.0009.phd 一般这种文件都很大,最好使用64位系统,不然会跑不...
IBM开发的强大的内存dump分析工具,IBM heapAnalyzer是通过分析OOM后的Java heap dump文件的,通过对dump文件的分析找到可能泄露的点,这是IBM官方的工具,它对堆栈调用做了可视化的转换,可以更直观地看到调用关系...