知识库

获取 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 的位置或生成崩溃转储文件的位置。例如,设置 PATH=<jdk>\jre\bin\client;%PATH%

不使用任何选项时,jmap 会打印共享对象映射。通常我们的分析所需的示例是:

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

上述命令将 Java 堆以二进制格式转储到 filename。如果使用可选的 live 子选项,将仅转储堆中的活动对象。

查看堆转储

要浏览如上所述生成的堆转储,可以使用 jhat (Java 堆分析工具) 读取生成的文件。

与 jmap 一起使用的一些有用选项包括:

  • -heap 打印堆摘要而不是二进制转储。

  • -histo[:live] 打印堆的柱状图。

  • 如果 pid 没有响应,可以使用 -F 选项与 jmap -dump 或 jmap -histo 选项一起使用。

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

语法

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

例如 jhat -port 7001 -debug 1

其中 -port 指定可以通过浏览器查看输出的端口,-debug <int> 指定呈现的调试详细信息级别。

我们还可以使用 jconsole 工具以图形格式查看 CPU、内存和堆的使用情况。

$ jconsole [ options ] [ connection ... ]

例如 jconsole -interval=5 <pid> 127.0.0.1:7474

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

参考资料

© . All rights reserved.