如何使用Java中的jmap分析堆转储

66

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

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

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

你尝试过使用 jmap -heap <process-id> > DumpFile.txt 吗? - Felix Reckers
1
这个文件在Eclipse MAT中打开很好,只需将其命名为.hprof扩展名即可。 - iTake
另请参阅https://dev59.com/8XVC5IYBdhLWcg3wykQt - rogerdpack
NetBeans可以读取这些文件。只需转到文件>打开文件...选择并打开它。 - undefined
8个回答

56

您应该使用 jmap -heap:format=b <process-id> 命令,而不需要添加路径。这样就会创建一个*.bin文件,您可以使用与jmap相同的路径下的jvisualvm.exe 打开它。这是一个很好的工具,可以打开此类转储文件。


2
从JDK 9开始,Visual VM将不再随Oracle JDK一起提供。希望在Oracle JDK 9或更高版本中使用Visual VM的开发人员可以从Visual VM开源项目网站获取它。 - Abdullah Khan
请注意,您需要“文件>加载...”堆转储(它不是核心转储)。请参阅:https://dev59.com/52w05IYBdhLWcg3wrDpS#37791314 - beerbajay

42
你可以使用 jhat(Java Heap Analysis Tool)来读取生成的文件:
jhat [ options ] <heap-dump-file>

jhat命令解析Java堆转储文件并启动Web服务器。jhat使您能够使用您喜欢的Web浏览器浏览堆转储。

请注意,您应该有一个二进制格式输出才能使用解析它。您可以使用选项以此格式生成转储。

-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是日志文件的名称。 - Chaitanya
尝试使用format=b选项进行转储,例如:jmap -dump:format=b,file=<filename> - user2030471
jhat 是一个不太用户友好的工具。 - Adam Dyga
我使用-XX:+HeapDumpOnOutOfMemoryError JVM选项在服务器上生成了一个16Gb的堆转储,并且jhat与之无缝配合。感谢这个好提示! - Elias Dorneles
使用jhat是一个不错的选择,因为我正在Linux上使用OpenJDK,它包括jhat,这使得使用openjdk成为一个简单的选择。 - JeremyCanfield

19

回答有些晚,但是值得快速浏览一下。只需要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 命令查找虚拟机 ID(即 JVM ID)

打开命令提示符窗口,输入以下命令 >

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

17252是我们需要的vmid。

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

使用jmap - 生成堆转储

从Java文档中了解jmap “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如何以10种方式监视和分析垃圾收集


10
如果您使用Eclipse作为IDE,我建议使用优秀的Eclipse插件memory analyzer
另一个选择是使用JVisualVM,它也可以读取(和创建)堆转储,并且随每个JDK一起提供。您可以在JDK的bin目录中找到它。

谢谢,我已经下载了软件来分析这个问题。 - Chaitanya

5

VisualVm是不包含在Apple JDK中的。你可以使用VisualVM Mac Application bundle(dmg)这个独立应用程序来弥补这一点。


-1

MAT、jprofiler 和 jhat 都是可能的选项。由于 jhat 随 jdk 一起提供,您可以轻松启动它进行一些基本分析。看看这个


-1

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


-1

如上面的大多数答案中提到的,您可以使用以下命令轻松进行堆转储:

jmap -dump:live,format=b,file=/path/to/mydump.hprof <pid>

<pid> - Java 进程 ID

使用图形化堆转储分析工具,例如 Eclipse MAT,可以很容易理解你刚刚获取的内容。

你需要 Eclipse IDEMemory Analyzer 插件 来开始使用。

更多详细信息请参阅this article


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接