知识库

获取 JVM 堆转储

本文档提供了在 Java 机器上创建堆转储以调查潜在内存泄漏的过程。

虽然通过指定 -XX:+HeapDumpOnOutOfMemoryError VM 选项在抛出 OutOfMemoryError 时会自动生成堆转储,但我们也可以使用 jmap 工具来打印共享对象的内存映射或给定进程、核心文件或远程调试服务器的堆内存细节。如果给定进程运行在 64 位 VM 上,可能需要指定 -J-d64 选项,例如:

$ jmap -J-d64 -heap <pid>

要获取机器上运行的 Java 进程列表,可使用 jpsjcmd 命令。

在缺少 dbgeng.dll 的 Windows 系统中,需要安装 “Debugging Tools For Windows” 才能使这些工具工作。另外,PATH 环境变量应包含目标进程使用的 jvm.dll 所在位置或产生 Crash Dump 文件的路径。例如,设置 PATH=<jdk>\jre\bin\client;%PATH%

如果不使用任何选项,jmap 将打印共享对象映射。我们分析时通常需要的示例如下:

$ jmap -dump:[live,]format=b,file=<filename>.bin <pid>

上述命令会以二进制格式将 Java 堆转储到指定文件名。如果使用了可选的 live 子选项,则只转储堆中的活跃对象。

查看堆转储

要浏览上述生成的堆转储文件,可以使用 jhat(Java Heap Analysis Tool)读取生成的文件。

使用 jmap 时一些有用的选项有:

  • -heap 在生成二进制转储之前打印堆摘要。

  • -histo[:live] 打印堆的直方图。

  • -F 可与 jmap -dump 或 jmap -histo 选项一起使用,适用于 PID 无响应的情况。

我们可以使用 jhat 命令解析 Java 堆转储文件并启动一个 Web 服务器,以通过浏览器查看堆转储。默认端口为 7000,但可以通过 -port 选项更改。

语法

$ jhat [ options ] <heap-dump-file>

e.g. jhat -port 7001 -debug 1

其中 -port 决定浏览器查看输出的端口,-debug <int> 决定显示的调试细节级别。

我们也可以使用 jconsole 工具以图形化方式查看 CPU、内存和堆使用情况。

$ jconsole [ options ] [ connection ... ]

e.g. jconsole -interval=5 <pid> 127.0.0.1:7474

其中 -interval=n 决定报告的刷新间隔(秒),<pid> 为目标 JVM 的进程 ID(JVM 必须与运行 jconsole 的用户 ID 相同)。

参考文献

© . This site is unofficial and not affiliated with Neo4j, Inc.