具有比 jmap 更高性能的堆转储创建替代方案?

Chr*_*ian 5 linux java dump heapspace

我必须创建堆转储,它与 jmap 配合得很好。我的问题是,jmap 创建 heapdump 文件需要很长时间。特别是当堆越来越大(> 1GB)时,它花费的时间太长。

一种情况为例:
当服务器遇到堆空间问题时,我想自动重新启动它并在重新启动之前创建一个堆转储。这有效,但编写堆转储需要很长时间。这样服务器停机时间太长了。heapdump 创建需要一个多小时。

我知道-XX:+HeapDumpOnOutOfMemoryError,但大多数时候我可以在 jvm 抛出异常之前找到内存问题。

是否有替代 jmap 的方法可以更快地写入堆转储?
对于上述示例的特殊解决方案也将不胜感激。

这个问题是编程和系统管理之间的混合,但我认为我来对地方了。

Chr*_*ian 8

我找到了我的问题的答案。 这个关于 serverfault 的另一个问题的答案给了我这个想法。

  1. 用 gdb 连接到你的 java 进程
    gdb --pid=<your java pid>
  2. 从 gdb 创建核心转储
    gcore <file name>
    detach
    quit
  3. 重新启动java进程或做任何你喜欢的事情
  4. 通过将 jmap 连接到核心转储,从核心转储创建堆转储
    jmap -heap:format=b <path to java binary> <core dump file>

在第 4 步中,指定正确的 java 二进制文件至关重要,否则 jmap 无法附加到核心转储。如果您不确定 java 进程使用了​​哪个二进制文件,请使用 gdb 打开核心转储:
gdb --core=<core dump file>
会有这样一行,告诉您完整路径:
Core was generated by '/opt/tomcat/bin/jsvc'.

创建核心转储比直接通过 jmap 创建堆转储要快得多。通过这种方式,您可以创建 Java 进程的堆转储,而不会停机太长时间。

编辑:
当您收到以下错误消息时,可能是您指定了错误的 Java 二进制文件:

Error attaching to core file: Can't attach to the core file
Run Code Online (Sandbox Code Playgroud)

要为 jmap 调用获取正确的 java 二进制文件,请使用 gdb 打开核心转储:

gdb --core=[path tp core file]
Run Code Online (Sandbox Code Playgroud)

会有这样一行,告诉你正确的二进制文件:

Core was generated by `/opt/tomcat/bin/jsvc'.
Run Code Online (Sandbox Code Playgroud)