如何在java中使用jmap分析堆转储

Posted

技术标签:

【中文标题】如何在java中使用jmap分析堆转储【英文标题】:How to analyse the heap dump using jmap in java 【发布时间】:2013-02-14 08:58:03 【问题描述】:

我正在使用以下命令创建堆转储:

jmap -dump:file=DumpFile.txt <process-id>

我已打开生成的文件 - DumpFile.txt,但它不是可读格式。 所以请告诉我如何分析生成文件中的数据。

【问题讨论】:

你试过jmap -heap &lt;process-id&gt; &gt; DumpFile.txt吗? 这个文件在 Eclipse MAT 中打开很好,只需给它 .hprof 扩展名 另见***.com/questions/185893/… 【参考方案1】:

如果你只是运行 jmap -histo:live 或 jmap -histo,它会在控制台上输出内容!

【讨论】:

【参考方案2】:

回答这个问题已经很晚了,但值得一看。只需 2 分钟即可详细了解。

首先创建这个java程序

import java.util.ArrayList;
import java.util.List;

public class GarbageCollectionAnalysisExample
    public static void main(String[] args) 
           List<String> l = new ArrayList<String>();
           for (int i = 0; i < 100000000; i++) 
                  l = new ArrayList<String>(); //Memory leak
                  System.out.println(l);
           
           System.out.println("Done");
    

使用 jps 查找 vmid(虚拟机 id 即 JVM id)

转到 CMD 并键入以下命令 >

C:\>jps
18588 Jps
17252 GarbageCollectionAnalysisExample
16048
2084 Main

17252 是我们需要的 vmid。

现在我们将学习如何使用 jmap 和 jhat

使用 jmap - 生成堆转储

来自关于 jmap 的 java 文档 “jmap 打印给定进程或核心文件或远程调试服务器的共享对象内存映射或堆内存详细信息”

使用以下命令生成堆转储>

C:\>jmap -dump:file=E:\heapDump.jmap 17252
Dumping heap to E:\heapDump.jmap ...
Heap dump file created

其中 17252 是 vmid(从上面挑选的)。

堆转储将在E:\heapDump.jmap中生成

现在使用 Jhat Jhat用于分析java中的垃圾收集转储 -

C:\>jhat E:\heapDump.jmap
Reading from E:\heapDump.jmap...
Dump file created Mon Nov 07 23:59:19 IST 2016
Snapshot read, resolving...
Resolving 241865 objects...
Chasing references, expect 48 dots................................................
Eliminating duplicate references................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

默认情况下,它将在端口 7000 上启动 http 服务器。 那我们就去http://localhost:7000/

礼貌:JMAP,How to monitor and analyze the garbage collection in 10 ways

【讨论】:

【参考方案3】:

VisualVm 不随 Apple JDK 一起提供。您可以将 VisualVM Mac Application bundle(dmg) 用作单独的应用程序来弥补这一点。

【讨论】:

【参考方案4】:

您应该使用jmap -heap:format=b &lt;process-id&gt; 而不使用任何路径。因此它会创建一个 *.bin 文件,您可以使用 jvisualvm.exe(与 jmap 相同的路径)打开该文件。这是打开此类转储文件的好工具。

【讨论】:

从 JDK 9 开始,Visual VM 将不包含在 Oracle JDK 中。想要将 Visual VM 与 Oracle JDK 9 或更高版本一起使用的开发人员可以从 Visual VM 开源项目站点获取它。 请注意,您需要File &gt; Load... 堆转储(它不是核心转储)。见:***.com/a/37791314/320220【参考方案5】:

MAT、jprofiler、jhat 是可能的选项。由于 jhat 自带 jdk,你可以很容易地启动它来做一些基本的分析。 check this out

【讨论】:

【参考方案6】:

您可以使用jhat(Java堆分析工具)读取生成的文件:

jhat [ options ] <heap-dump-file>

jhat 命令解析一个 java 堆转储文件并启动一个网络服务器。 jhat 使您能够使用自己喜欢的网络浏览器浏览堆转储。

请注意,您应该有一个hprof 二进制格式输出,以便能够使用jhat 对其进行解析。您可以使用format=b 选项以这种格式生成转储。

-dump:format=b,file=<filename>

【讨论】:

我运行 jhat 命令来分析堆转储文件,但出现以下错误:Reading from 447start.out... java.io.IOException: Unrecognized magic number: 1027423549 at com.sun.tools.hat.internal.parser.Reader.readFile(Reader.java:81) at com.sun.tools.hat.Main.main(Main.java:143) 这里 447start.out 是日志文件的名称。 尝试使用 format=b 选项转储,如下所示:jmap -dump:format=b,file=&lt;filename&gt; jhat 不是一个用户友好的工具 我使用-XX:+HeapDumpOnOutOfMemoryError jvm 选项在服务器上生成了一个 16Gb 堆转储,jhat 使用它运行顺畅。谢谢你的好提示! 使用 jhat 是一个不错的选择,因为我在 Linux 上使用 OpenJDK,其中包括 jhat,这使得使用 openjdk 成为一个简单的选择。【参考方案7】:

如果你使用 Eclipse 作为你的 IDE,我会推荐优秀的 eclipse 插件memory analyzer

另一个选择是使用 JVisualVM,它也可以读取(和创建)堆转储,并且随每个 JDK 一起提供。您可以在 JDK 的 bin 目录中找到它。

【讨论】:

谢谢我下载软件分析问题。

以上是关于如何在java中使用jmap分析堆转储的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Java虚拟机——虚拟机堆转储快照分析工具(jhat)

使用 jmap 命令的 Java 堆转储错误:过早的 EOF

为啥我的 Java 堆转储大小比已用内存小得多?

内存泄漏的java堆和线程分析

jhat:虚拟机堆转储快照分析工具

如果应用程序在 GC 中,如何可靠地获取 JVM 核心转储?