用于分析大型Java堆转储的工具

Rol*_*lig 73 java profiling

我有一个我想分析的HotSpot JVM堆转储.VM运行时-Xmx31g,堆转储文件大48 GB.

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

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

Fra*_*See 67

通常情况下,我使用的内容ParseHeapDump.sh包含在Eclipse Memory Analyzer中,在此处进行了描述,我将其添加到我们更强大的服务器上(通过linux下载和复制.zip发行版,在那里解压缩).shell脚本比从GUI解析堆需要更少的资源,而且你可以在更强大的资源上运行它(你可以通过添加类似于-vmargs -Xmx40g -XX:-UseGCOverheadLimit脚本最后一行末尾的内容来分配更多资源.例如,修改后该文件的最后一行可能如下所示

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit
Run Code Online (Sandbox Code Playgroud)

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

在成功之后,它会在.hprof文件旁边创建许多"索引"文件.

在创建索引之后,我尝试从中生成报告并将这些报告scp到我的本地计算机,并尝试查看是否可以找到罪魁祸首(不仅仅是报告,而不是索引).这是一个关于创建报告的教程.

示例报告:

./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects
Run Code Online (Sandbox Code Playgroud)

其他报告选项:

org.eclipse.mat.api:overvieworg.eclipse.mat.api:top_components

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

编辑: 我只想添加两个注释:

  • 据我所知,只有索引的生成是Eclipse MAT的内存密集型部分.获得索引之后,Eclipse MAT中的大多数处理都不需要那么多内存.
  • 在shell脚本上执行此操作意味着我可以在无头服务器上执行此操作(我通常也会在无头服务器上执行此操作,因为它们通常是最强大的服务器).如果你有一个可以生成该大小的堆转储的服务器,那么你可能还有另一台服务器可以处理那么多的堆转储.

  • 重要提示:`ParseHeapDump.sh`仅与Linux版本打包,而不是OSX版本 - http://www.eclipse.org/mat/downloads.php (4认同)
  • 嗯,较新版本的ParseHeapDump.sh想直接运行./MemoryAnalyzer.我正在尝试直接用java运行启动器,到目前为止看起来似乎有效,例如java -Xmx16g -Xms16g -jar plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar -consoleLog -consolelog -application org.eclipse.mat.api.parse"$ @" (2认同)

Mic*_*ael 6

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

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

如果您期望一个漂亮的GUI工具,大多数其他堆分析器(我使用IBM http://www.alphaworks.ibm.com/tech/heapanalyzer)至少需要比堆大一部分RAM.

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

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


小智 6

第一步:增加分配给 MAT 的 RAM 量。默认情况下,它不是很多,也无法打开大文件。

如果在 MAC (OSX) 上使用 MAT,您将在 MemoryAnalyzer.app/Contents/MacOS 中拥有文件 MemoryAnalyzer.ini 文件。对该文件进行调整并让它们“接受”对我来说不起作用。您可以改为基于此文件的内容创建修改后的启动命令/shell 脚本并从该目录运行它。就我而言,我想要 20 GB 堆:

./MemoryAnalyzer -vmargs -Xmx20g --XX:-UseGCOverheadLimit ... other params desired
Run Code Online (Sandbox Code Playgroud)

只需通过终端从 Contents/MacOS 目录运行此命令/脚本,即可使用更多可用 RAM 启动 GUI。


Pet*_*rey 5

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


rog*_*ack 5

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

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

https://github.com/aragozin/heaplib

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