获取 JVM 堆转储
本文档提供了在 Java 机器上创建堆转储以调查潜在内存泄漏的过程。
虽然通过指定 -XX:+HeapDumpOnOutOfMemoryError VM 选项在抛出 OutOfMemoryError 时会自动生成堆转储,但我们也可以使用 jmap 工具来打印共享对象的内存映射或给定进程、核心文件或远程调试服务器的堆内存细节。如果给定进程运行在 64 位 VM 上,可能需要指定 -J-d64 选项,例如:
$ jmap -J-d64 -heap <pid>
要获取机器上运行的 Java 进程列表,可使用 jps 或 jcmd 命令。
在缺少 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 相同)。
参考文献
此页面有帮助吗?