简体   繁体   English

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

[英]Tool for analyzing large Java heap dumps

I have a HotSpot JVM heap dump that I would like to analyze.我有一个想要分析的 HotSpot JVM 堆转储。 The VM ran with -Xmx31g , and the heap dump file is 48 GB large. VM 使用-Xmx31g运行,堆转储文件大小为 48 GB。

  • I won't even try jhat , as it requires about five times the heap memory (that would be 240 GB in my case) and is awfully slow.我什至不会尝试jhat ,因为它需要大约五倍的堆内存(在我的情况下是 240 GB)并且非常慢。
  • Eclipse MAT crashes with an ArrayIndexOutOfBoundsException after analyzing the heap dump for several hours.在分析堆转储几个小时后,Eclipse MAT 崩溃并出现ArrayIndexOutOfBoundsException

What other tools are available for that task?还有哪些其他工具可用于该任务? A suite of command line tools would be best, consisting of one program that transforms the heap dump into efficient data structures for analysis, combined with several other tools that work on the pre-structured data.一套命令行工具是最好的,它由一个程序组成,将堆转储转换为有效的数据结构以供分析,并结合其他几个处理预结构化数据的工具。

Normally, what I use is ParseHeapDump.sh included within Eclipse Memory Analyzer and described here , and I do that onto one our more beefed up servers (download and copy over the linux .zip distro, unzip there).通常,我使用的是包含在Eclipse 内存分析器中在此处描述的ParseHeapDump.sh ,我在我们更强大的服务器上执行此操作(下载并复制 linux .zip 发行版,然后在那里解压缩)。 The shell script needs less resources than parsing the heap from the GUI, plus you can run it on your beefy server with more resources (you can allocate more resources by adding something like -vmargs -Xmx40g -XX:-UseGCOverheadLimit to the end of the last line of the script. For instance, the last line of that file might look like this after modification与从 GUI 解析堆相比,shell 脚本需要的资源更少,而且您可以在具有更多资源的强大服务器上运行它(您可以通过在末尾添加-vmargs -Xmx40g -XX:-UseGCOverheadLimit来分配更多资源脚本的最后一行。例如,该文件的最后一行修改后可能如下所示

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

Run it like ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof一样运行它

After that succeeds, it creates a number of "index" files next to the .hprof file.成功后,它会在 .hprof 文件旁边创建许多“索引”文件。

After creating the indices, I try to generate reports from that and scp those reports to my local machines and try to see if I can find the culprit just by that (not just the reports, not the indices).创建索引后,我尝试从中生成报告并将这些报告 scp 到我的本地计算机,并尝试查看是否可以仅通过该报告(不仅仅是报告,而不是索引)找到罪魁祸首。 Here's a tutorial on creating the reports .这是有关创建报告的教程。

Example report:示例报告:

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

Other report options:其他报告选项:

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

If those reports are not enough and if I need some more digging (ie let's say via oql), I scp the indices as well as hprof file to my local machine, and then open the heap dump (with the indices in the same directory as the heap dump) with my Eclipse MAT GUI.如果这些报告还不够,并且我需要更多的挖掘(即让我们说通过 oql),我将索引以及 hprof 文件 scp 到我的本地机器,然后打开堆转储(索引与堆转储)与我的 Eclipse MAT GUI。 From there, it does not need too much memory to run.从那里,它不需要太多的内存来运行。

EDIT: I just liked to add two notes :编辑:我只是喜欢添加两个注释:

  • As far as I know, only the generation of the indices is the memory intensive part of Eclipse MAT.据我所知,只有索引的生成是 Eclipse MAT 的内存密集部分。 After you have the indices, most of your processing from Eclipse MAT would not need that much memory.有了索引之后,大部分来自 Eclipse MAT 的处理就不需要那么多内存了。
  • Doing this on a shell script means I can do it on a headless server (and I normally do it on a headless server as well, because they're normally the most powerful ones).在 shell 脚本上执行此操作意味着我可以在无头服务器上执行此操作(我通常也在无头服务器上执行此操作,因为它们通常是最强大的服务器)。 And if you have a server that can generate a heap dump of that size, chances are, you have another server out there that can process that much of a heap dump as well.如果您有一台可以生成这种大小的堆转储的服务器,很有可能您还有另一台服务器也可以处理如此多的堆转储。

First step: increase the amount of RAM you are allocating to MAT.第一步:增加分配给 MAT 的 RAM 量。 By default it's not very much and it can't open large files.默认情况下,它不是很多,也无法打开大文件。

In case of using MAT on MAC (OSX) you'll have file MemoryAnalyzer.ini file in MemoryAnalyzer.app/Contents/MacOS.如果在 MAC (OSX) 上使用 MAT,您将在 MemoryAnalyzer.app/Contents/MacOS 中拥有文件 MemoryAnalyzer.ini 文件。 It wasn't working for me to make adjustments to that file and have them "take".对该文件进行调整并让它们“接受”对我来说不起作用。 You can instead create a modified startup command/shell script based on content of this file and run it from that directory.您可以改为基于此文件的内容创建修改后的启动命令/shell 脚本并从该目录运行它。 In my case I wanted 20 GB heap:就我而言,我想要 20 GB 堆:

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

Just run this command/script from Contents/MacOS directory via terminal, to start the GUI with more RAM available.只需通过终端从 Contents/MacOS 目录运行此命令/脚本,即可使用更多可用 RAM 启动 GUI。

The accepted answer to this related question should provide a good start for you (uses live jmap histograms instead of heap dumps):这个相关问题的公认答案应该为您提供一个良好的开端(使用实时 jmap 直方图而不是堆转储):

Method for finding memory leak in large Java heap dumps 在大型Java堆转储中查找内存泄漏的方法

Most other heap analysers (I use IBM http://www.alphaworks.ibm.com/tech/heapanalyzer ) require at least a percentage of RAM more than the heap if you're expecting a nice GUI tool.大多数其他堆分析器(我使用 IBM http://www.alphaworks.ibm.com/tech/heapanalyzer )如果您期待一个不错的 GUI 工具,至少需要比堆多一定百分比的 RAM。

Other than that, many developers use alternative approaches, like live stack analysis to get an idea of what's going on.除此之外,许多开发人员使用替代方法,例如实时堆栈分析来了解正在发生的事情。

Although I must question why your heaps are so large?虽然我必须质疑为什么你的堆这么大? The effect on allocation and garbage collection must be massive.对分配和垃圾收集的影响一定是巨大的。 I'd bet a large percentage of what's in your heap should actually be stored in a database / a persistent cache etc etc.我敢打赌,堆中的大部分内容实际上应该存储在数据库/持久缓存等中。

I suggest trying YourKit.我建议尝试 YourKit。 It usually needs a little less memory than the heap dump size (it indexes it and uses that information to retrieve what you want)它通常需要比堆转储大小少一点的内存(它索引它并使用该信息来检索你想要的)

A few more options:还有几个选项:

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

wrote a custom Netbeans heap analyzer that just exposes a "query style" interface through the heap dump file, instead of actually loading the file into memory.编写了一个自定义的 Netbeans 堆分析器,它只是通过堆转储文件公开一个“查询样式”接口,而不是实际将文件加载到内存中。

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

Though I don't know if "his query language" is better than the eclipse OQL mentioned in the accepted answer here.虽然我不知道“他的查询语言”是否比这里接受的答案中提到的 eclipse OQL 更好。

JProfiler 8.1 ($499 for user license) is also said to be able to traverse large heaps without using a lot of money.据说JProfiler 8.1(用户许可证 499 美元)还可以在不使用大量资金的情况下遍历大型堆。

A not so well known tool - http://dr-brenschede.de/bheapsampler/ works well for large heaps.一个不太知名的工具 - http://dr-brenschede.de/bheapsampler/适用于大堆。 It works by sampling so it doesn't have to read the entire thing, though a bit finicky.它通过采样工作,因此它不必阅读整个内容,尽管有点挑剔。

The latest snapshot build of Eclipse Memory Analyzer has a facility to randomly discard a certain percentage of objects to reduce memory consumption and allow the remaining objects to be analyzed. Eclipse Memory Analyzer 的最新快照版本具有随机丢弃一定百分比的对象以减少内存消耗并允许分析剩余对象的功能。 See Bug 563960 and the nightly snapshot build to test this facility before it is included in the next release of MAT.请参阅错误 563960夜间快照构建,以在下一个 MAT 版本中包含此功能之前对其进行测试。

This is not a command line solution, however I like the tools:这不是命令行解决方案,但我喜欢这些工具:

Copy the heap dump to a server large enough to host it.将堆转储复制到足以承载它的服务器。 It is very well possible that the original server can be used.很可能可以使用原始服务器。

Enter the server via ssh -X to run the graphical tool remotely and use jvisualvm from the Java binary directory to load the .hprof file of the heap dump.通过输入服务器ssh -X运行远程图形化工具,并使用jvisualvm从Java二进制文件目录加载.hprof堆转储文件。

The tool does not load the complete heap dump into memory at once, but loads parts when they are required.该工具不会立即将完整的堆转储加载到内存中,而是在需要时加载部分。 Of course, if you look around enough in the file the required memory will finally reach the size of the heap dump.当然,如果您在文件中环顾四周,所需的内存最终将达到堆转储的大小。

尝试使用 jprofiler ,它在分析大型 .hprof 方面效果很好,我尝试过使用大小约为 22 GB 的文件。

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

I came across an interesting tool called JXray.我遇到了一个有趣的工具,叫做 JXray。 It provides limited evaluation trial license.它提供有限的评估试用许可证。 Found it very useful to find memory leaks.发现查找内存泄漏非常有用。 You may give it a shot.你可以试一试。

When the problem can be "easily" reproduced, one unmentioned alternative is to take heap dumps before memory grows that big ( eg<\/em> , jmap -dump:format=b,file=heap.bin <pid><\/code> ).当问题可以“轻松”重现时,一种未提及的替代方法是在内存增长到那么大之前进行堆转储(例如<\/em>, jmap -dump:format=b,file=heap.bin <pid><\/code> )。

In many cases you will already get an idea of what's going on without waiting for an OOM.在许多情况下,您无需等待 OOM 即可了解正在发生的事情。

In addition, MAT provides a feature to compare different snapshots, which can come handy (see https:\/\/stackoverflow.com\/a\/55926302\/898154<\/a> for instructions and a description).此外,MAT 提供了比较不同快照的功能,可以派上用场(有关说明和说明,请参见https:\/\/stackoverflow.com\/a\/55926302\/898154<\/a> )。

"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM