我有一个HotSpot JVM堆转储,我想分析一下。VM使用运行-Xmx31g
,堆转储文件大48 GB。
- 我什至不会尝试
jhat
,因为它需要大约五倍的堆内存(在我的情况下为240 GB),而且速度非常慢。 ArrayIndexOutOfBoundsException
在分析了几个小时的堆转储后,Eclipse MAT崩溃了。
还有哪些其他工具可用于该任务?最好使用一套命令行工具,其中包括一个程序,该程序将堆转储转换为有效的数据结构以进行分析,再结合使用其他几个可处理预构建数据的工具。
我有一个HotSpot JVM堆转储,我想分析一下。VM使用运行-Xmx31g
,堆转储文件大48 GB。
jhat
,因为它需要大约五倍的堆内存(在我的情况下为240 GB),而且速度非常慢。ArrayIndexOutOfBoundsException
在分析了几个小时的堆转储后,Eclipse MAT崩溃了。还有哪些其他工具可用于该任务?最好使用一套命令行工具,其中包括一个程序,该程序将堆转储转换为有效的数据结构以进行分析,再结合使用其他几个可处理预构建数据的工具。
Answers:
通常,我使用的内容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:overview
和 org.eclipse.mat.api:top_components
如果这些报告还不够,并且还需要进一步挖掘(例如,通过oql进行说明),我会将索引以及hprof文件scp到本地计算机,然后打开堆转储(索引与以下目录位于同一目录中)堆转储)和我的Eclipse MAT GUI。从那里开始,它不需要太多的内存即可运行。
编辑: 我只是喜欢添加两个说明:
ParseHeapDump.sh
仅打包为Linux版本,不打包为OSX版本-eclipse.org/mat/downloads.php
这个相关问题的公认答案应该为您提供一个良好的开始(使用实时jmap直方图而不是堆转储):
如果您期望一个不错的GUI工具,大多数其他堆分析器(我使用IBM http://www.alphaworks.ibm.com/tech/heapanalyzer)至少需要比堆多一点RAM的内存。
除此之外,许多开发人员还使用其他方法,例如实时堆栈分析来了解正在发生的事情。
尽管我必须质疑为什么您的堆这么大?对分配和垃圾回收的影响必须是巨大的。我敢打赌,您堆中的大部分内容实际上应该存储在数据库/持久性缓存等中。
其他一些选择:
这个人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美元)也据说可以在不花费大量金钱的情况下遍历大堆。
第一步:增加分配给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。
一个不太知名的工具-http://dr-brenschede.de/bheapsampler/适用于大型堆。它通过采样工作,因此虽然有点挑剔,但不必阅读整个内容。
Eclipse Memory Analyzer的最新快照构建具有一种功能,可以随机丢弃一定百分比的对象以减少内存消耗并允许分析其余对象。请参阅Bug 563960和每晚快照版本以测试此功能,然后将其包含在下一版本的MAT中。
我遇到了一个有趣的工具,叫做JXray。它提供了有限的评估试用许可证。发现查找内存泄漏非常有用。您可以试一试。
ArrayIndexOutOfBoundsException
至少有两个 bug的特点。我之所以这样说是因为您在运行MAT时尚未报告OOME,而MAT具有不同的修复。