我有一个我想分析的HotSpot JVM堆转储。 VM以-Xmx31g
运行,堆转储文件大48 GB。
jhat
,因为它需要大约五倍的堆内存(在我的情况下会是240 GB)并且非常慢。ArrayIndexOutOfBoundsException
崩溃。该任务还有哪些其他工具可用?一套命令行工具是最好的,包括一个程序,它将堆转储转换为高效的数据结构进行分析,并与其他几个处理预结构化数据的工具相结合。
答案 0 :(得分:59)
通常情况下,我使用的ParseHeapDump.sh
包含Eclipse Memory Analyzer并描述here,我会将其添加到我们更强大的服务器上(通过linux下载和复制.zip发行版,在那里解压缩)。 shell脚本比从GUI解析堆需要的资源少,而且你可以在你的服务器上用更多的资源运行它(你可以通过在{10}的末尾添加类似-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到我的本地计算机并尝试查看是否可以找到罪魁祸首(不仅仅是报告,而不是索引)。这是关于creating the reports的教程。
示例报告:
./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与堆转储相同的目录。从那里开始,它不需要太多的内存来运行。
修改强> 我只想添加两个注释:
答案 1 :(得分:5)
此相关问题的接受答案应该为您提供一个良好的开端(使用实时jmap直方图而不是堆转储):
Method for finding memory leak in large Java heap dumps
如果你期望一个漂亮的GUI工具,那么大多数其他堆分析器(我使用IBM http://www.alphaworks.ibm.com/tech/heapanalyzer)至少需要比堆高一个百分比的RAM。
除此之外,许多开发人员使用其他方法,例如实时堆栈分析,以了解正在发生的事情。
虽然我必须质疑为什么你的堆如此之大?对分配和垃圾收集的影响必须是巨大的。我敢打赌,你的堆中的很大一部分实际上应该存储在数据库/持久缓存等中。
答案 2 :(得分:4)
还有一些选择:
此人http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html
编写了一个自定义的Netbeans堆分析器,它只暴露了一种"查询样式"通过堆转储文件接口,而不是实际将文件加载到内存中。
https://github.com/aragozin/jvm-tools/tree/master/hprof-heap
虽然我不知道他的查询语言是否是"比这里接受的答案中提到的日食OQL更好。
JProfiler 8.1(499美元的用户许可证)也said能够在不使用大量资金的情况下遍历大堆。
答案 3 :(得分:3)
我建议尝试YourKit。它通常需要比堆转储大小少一点的内存(它将其编入索引并使用该信息来检索您想要的内容)
答案 4 :(得分:3)
第一步:增加分配给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。
答案 5 :(得分:2)
一个不太知名的工具 - http://dr-brenschede.de/bheapsampler/适用于大堆。它通过采样工作,所以它不需要阅读整个事情,虽然有点挑剔。
答案 6 :(得分:2)
Eclipse Memory Analyzer的最新快照构建具有一种功能,可以随机丢弃一定百分比的对象以减少内存消耗并允许分析其余对象。在此功能包含在下一版MAT中之前,请参见Bug 563960和nightly snapshot build对其进行测试。
答案 7 :(得分:0)
这不是命令行解决方案,但是我喜欢这些工具:
将堆转储复制到足够托管它的服务器。很有可能可以使用原始服务器。
通过ssh -X
输入服务器以远程运行图形工具,并使用Java二进制目录中的jvisualvm
加载堆转储的.hprof
文件。
该工具不会立即将整个堆转储加载到内存中,而是在需要时加载部件。当然,如果您在文件中四处查看,所需的内存将最终达到堆转储的大小。
答案 8 :(得分:0)
尝试使用jprofiler,它可以很好地分析大型.hprof,我尝试使用的文件大小约为22 GB。
https://www.ej-technologies.com/products/jprofiler/overview.html
答案 9 :(得分:0)
我遇到了一个有趣的工具,叫做JXray。它提供了有限的评估试用许可证。发现查找内存泄漏非常有用。您可以试一试。