分析大型Java堆转储的工具


80

我有一个HotSpot JVM堆转储,我想分析一下。VM使用运行-Xmx31g,堆转储文件大48 GB。

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

还有哪些其他工具可用于该任务?最好使用一套命令行工具,其中包括一个程序,该程序将堆转储转换为有效的数据结构以进行分析,再结合使用其他几个可处理预构建数据的工具。


您确定转储没有损坏,并且您正在使用DTFJ JAR的较新版本吗?ArrayIndexOutOfBoundsException至少有两个 bug的特点。我之所以这样说因为您在运行MAT时尚未报告OOME,而MAT具有不同的修复
Vineet Reynolds

jhat使用heapMap存储读取的对象,该对象随堆中存储的对象数量呈指数增长。一种选择是将decl的值从heapMap更改为TreeMap,然后运行jhat的堆大小至少与您的进程一样大。
codeDr

Answers:


78

通常,我使用的内容ParseHeapDump.sh包含在Eclipse Memory Analyzer中,在此处进行了描述,并将其添加到我们功能更强大的服务器上(通过linux .zip发行版下载并复制,然后在其中解压缩)。与从GUI解析堆相比,shell脚本所需的资源更少,此外,您可以在具有更多资源的强大服务器上运行它(您可以通过-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文件旁边创建许多“索引”文件。

创建索引后,我尝试从中生成报告并将这些报告scp到本地计算机,并尝试查看是否可以仅凭此找到罪魁祸首(不仅是报告,还不是索引)。这是有关创建报告的教程。

报告示例:

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

其他报告选项:

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

如果这些报告还不够,并且还需要进一步挖掘(例如,通过oql进行说明),我会将索引以及hprof文件scp到本地计算机,然后打开堆转储(索引与以下目录位于同一目录中)堆转储)和我的Eclipse MAT GUI。从那里开始,它不需要太多的内存即可运行。

编辑: 我只是喜欢添加两个说明:

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

4
重要说明:ParseHeapDump.sh仅打包为Linux版本,不打包为OSX版本-eclipse.org/mat/downloads.php
Christopher

当我尝试此操作(在Linux机器上使用bash进行打击)时,它立即失败,显示“无法初始化GTK +”。因此,看起来(当前版本为2016-04-15)仍然认为它正在与UI(?)对话。
查尔斯·罗斯

2
嗯,较新版本的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“ $ @”
Charles Roth

似乎可以通过下载Linux和OSX版本在OS X上使用它,然后将ParseHeapDump.sh复制到与MemoryAnalyze文件相同的目录(在我的情况下为〜/ Downloads / mat.app / Contents / MacOS),然后进行修改和在那里运行。或者,当然也可以通过SSH在某个远程服务器上运行它:)
rogerdpack '16

使用不超过500MB内存的Eclipse Memory Analyzer GUI打开了2GB的堆转储。索引文件是在打开文件时动态创建的(耗时约30秒)。也许他们改进了该工具。如果确实如此,它比来回复制大文件更方便。即使没有任何控制台实用程序,内存占用也很小,这对我来说是一大优势。但是老实说,我并没有尝试过很大的转储(超过50 GB)。非常有趣的是,使用此工具打开和分析如此大的转储需要多少内存。
Ruslan Stelmachenko '18年

6

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

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

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

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

尽管我必须质疑为什么您的堆这么大?对分配和垃圾回收的影响必须是巨大的。我敢打赌,您堆中的大部分内容实际上应该存储在数据库/持久性缓存等中。


5

我建议尝试使用YourKit。它通常需要比堆转储大小少的内存(它会对其进行索引并使用该信息来检索所需的内容)


4

其他一些选择:

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

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

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

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

JProfiler 8.1(用户许可的价格为499美元)也据说可以在不花费大量金钱的情况下遍历大堆。


github.com/on-site/fasthat不同,实际上是在大转储上工作。真好!
杰西·格里克

4

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

如果在MAC(OSX)上使用MAT,则在MemoryAnalyzer.app/Contents/MacOS中将具有MemoryAnalyzer.ini文件。对我来说,对该文件进行调整并让它们“采用”是没有用的。相反,您可以根据此文件的内容创建修改后的启动命令/ shell脚本,然后从该目录运行它。就我而言,我想要20 GB的堆:

./MemoryAnalyzer -vmargs -Xmx20g --XX:-UseGCOverheadLimit ... other params desired

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


谢谢。今天使用该实用程序。尝试2次单击运行,但显示错误。看着日志,无法创建数据文件,并说要使用开关。打开.app包,并在Eclipse \文件夹而非\ MacOS中找到MemoryAnalyzer.ini。啊哈!因此,我在本地提取了所有文件,并按照您的建议进行了操作。我在\ MacOS中创建了一个.sh文件,并将Eclipse \ MemoryAnalyzer.ini中的命令作为单行移动到了其中。保存的文件。在命令行上从MacOS \运行.sh文件,瞧,它起作用了。
马特·坎贝尔


2

Eclipse Memory Analyzer的最新快照构建具有一种功能,可以随机丢弃一定百分比的对象以减少内存消耗并允许分析其余对象。请参阅Bug 563960每晚快照版本以测试此功能,然后将其包含在下一版本的MAT中。


1

这不是命令行解决方案,但是我喜欢这些工具:

将堆转储复制到足够托管它的服务器。很有可能可以使用原始服务器。

通过输入服务器ssh -X以远程运行图形工具,并使用jvisualvmJava二进制目录中的加载.hprof堆转储文件。

该工具不会立即将整个堆转储加载到内存中,而是在需要时加载部件。当然,如果您在文件中四处张望,则所需的内存将最终达到堆转储的大小。


0

尝试使用jprofiler,它可以很好地分析大型.hprof,我尝试使用的文件大小约为22 GB。

https://www.ej-technologies.com/products/jprofiler/overview.html

0

我遇到了一个有趣的工具,叫做JXray。它提供了有限的评估试用许可证。发现查找内存泄漏非常有用。您可以试一试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.