分析大型Java堆转储的工具

我有一个我想分析的热点JVM堆转储。 VM运行-Xmx31g ,堆转储文件大小为48 GB。

  • 我甚jhat不会尝试jhat ,因为它需要大约五倍的堆内存(在我的情况下,这将是240 GB),非常慢。
  • 在分析堆转储几个小时之后,Eclipse MAT与ArrayIndexOutOfBoundsException崩溃。

该任务还有哪些其他工具可用? 一套命令行工具是最好的,它由一个程序组成,该程序将堆转储转换为高效的数据结构进行分析,并结合其他几个工具处理预结构化数据。

通常情况下,我使用的是Eclipse内存分析器中包含的ParseHeapDump.sh ,并在这里进行了描述,然后将其join到我们更加强大的服务器上(通过linux.zip distro下载并复制,解压缩到那里)。 shell脚本所需的资源比从GUI分析堆时less,另外你可以用更多的资源在你的服务器上运行它(你可以通过添加类似-vmargs -Xmx40g -XX:-UseGCOverheadLimit来分配更多的资源-vmargs -Xmx40g -XX:-UseGCOverheadLimit到末尾例如,该文件的最后一行可能会在修改后看起来像这样

 ./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit 

运行它像./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

在成功之后,它会在.hprof文件旁创build一些“索引”文件。

在创build索引之后,我试着从那里生成报告,并将这些报告提交给本地机器,并试图看看是否能够find罪魁祸首(不仅仅是报告,而不仅仅是索引)。 这是一个关于创build报告的教程。

示例报告:

 ./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects 

如果这些报告是不够的,如果我需要更多的挖掘(即让我们说通过oql),我scp索引以及hprof文件到我的本地机器,然后打开堆转储(与索引在同一目录中堆转储)与我的Eclipse MAT GUI。 从那里,它不需要太多的内存运行。

编辑:我只是喜欢加两个笔记:

  • 据我所知,只有索引的产生是Eclipse MAT的内存密集部分。 在获得索引后,Eclipse MAT的大部分处理将不需要太多的内存。
  • 在一个shell脚本中这样做意味着我可以在一个无头的服务器上执行它(我通常也是在无头的服务器上执行它,因为它们通常是最强大的服务器)。 如果你有一个服务器可以生成一个这样大小的堆转储,那么你有另外一台服务器可以处理大量的堆转储。

这个相关问题的接受答案应该为您提供一个良好的开端(使用实时jmap直方图而不是堆转储):

在大型Java堆转储中查找内存泄漏的方法

大多数其他堆分析器(我使用IBM http://www.alphaworks.ibm.com/tech/heapanalyzer )至less需要一个比堆更多的RAM,如果你期望一个很好的GUI工具。

除此之外,许多开发人员使用替代方法,如实时堆栈分析来了解正在发生的事情。

虽然我必须质疑为什么你的堆是如此之大? 对分配和垃圾收集的影响必须很大。 我敢打赌,你的堆中的大部分内容实际上应该存储在数据库/持久性caching等中。

我build议尝试YourKit。 它通常只需要比堆转储大小less一点的内存(它为它编制索引并使用该信息来检索你想要的内容)

这个人

http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html

写了一个自定义Netbeans堆分析器,通过堆转储文件公开一个“查询风格”接口,而不是实际加载到内存中的文件。

https://github.com/aragozin/jvm-tools/tree/master/hprof-heap

虽然我不知道“他的查询语言”是否比在这里接受的答案中提到的eclipse OQL更好。

一个不是很知名的工具 – http://dr-brenschede.de/bheapsampler/适用于大型堆。; 它通过抽样工作,所以它不必阅读整个事情,虽然有点挑剔。

如果在MAC(OSX)上使用MAT,您将在MemoryAnalyzer.app/Contents/MacOS中有文件MemoryAnalyzer.ini文件。 这不是为我工作。 您可以根据此文件的内容创build修改的启动命令/ shell脚本,并从该目录运行它。 在我的情况下,我想要20 GB的堆:

 ./MemoryAnalyzer -startup ../../../plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar --launcher.library ../../../plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.300.v20150602-1417 -vmargs -Xmx20g --XX:-UseGCOverheadLimit -Dorg.eclipse.swt.internal.carbon.smallFonts -XstartOnFirstThread 

只需通过terminal从Contents / MacOS目录运行这个命令/脚本,启动更多可用RAM的GUI。