JVM堆内存转储

堆转储是 JVM 中特定时刻内存中的所有对象的快照。它们对于解决内存泄漏问题并优化 Java 应用程序中的内存使用情况非常有用。

堆转储通常以二进制格式 hprof 文件存储。我们可以使用 jhat 或 JVisualVM 等工具打开和分析这些文件。

下面介绍两种堆转储的方式:

1. JCMD

  jcmd 是一个非常完整的工具,它通过向 JVM 发送命令请求来工作。我们必须在运行 Java 进程的同一台计算机上使用它。

  其众多命令之一是 GC.heap_dump。我们只需指定进程的 pid 和输出文件路径,就可以使用它来获取堆转储:

jcmd <pid> GC.heap_dump <file-path>

  例如:

[root@cwy-hbcsh-zyl-1 HDTool]# jps
22387 jar
17925 jar
13383 jar
26682 Jps
21422 jar
[root@cwy-hbcsh-zyl-1 HDTool]# jcmd 17925 GC.heap_dump /opt/HDTool/dump.hprof
17925:
Heap dump file created
[root@cwy-hbcsh-zyl-1 HDTool]#

2. 自动捕捉head dump

  上面工具jcmd旨在在特定时间手动捕获堆转储。在某些情况下,我们希望在发生内存溢出错误 java.lang.OutOfMemoryError 时, JVM自动执行堆内存转储,以方便事后进行排查和分析。

  JVM提供了一个命令行启动参数 HeapDumpOnOutOfMemoryError, 使用的格式为:

java -XX:+HeapDumpOnOutOfMemoryError
  • 如果不用 HeapDumpPath 选项指定转储路径,则会自动保存到启动目录下,文件名的格式为: 
java_pid<pid>.hprof
  • 指定 HeapDumpPath 参数的使用示例如下:
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path>

   对于某个应用服务,启动脚本中设置内存溢出转储路径为/opt/logs/app。如下:

特别说明:不建议内存溢出文件名写死,建议只写路径;否则,再次发生内存溢出,内存溢出文件无法成功保存。

   如下:文件命名为heapdump.hprof,下次发生内存溢出,再次生成的heapdump.hprof无法保存

   无法保存的提示如下:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to /opt/logs/app/heapdump.hprof ...
Unable to create /opt/logs/app/heapdump.hprof: 文件已存在

 

posted @ 2022-07-31 23:47  查拉图斯特拉面条  阅读(199)  评论(0编辑  收藏  举报