heapdumps的创build方法比jmap更高性能吗?

我必须创buildheapdumps,这与jmap很好。 我的问题是,该jmap需要很长的时间来创buildheapdump文件。 特别是堆越来越大(> 1GB)时间太长。

一个情况为例:
当服务器遇到堆空间问题时,我想要自动重新启动并在重新启动之前创build一个堆转储。 这可以起作用,但是写入heapdump需要很长时间。 这样服务器停机时间太长了。 heapdump创build需要超过一个小时。

我知道关于-XX:+HeapDumpOnOutOfMemoryError ,但是大部分时间我可以在jvm抛出exception之前find内存问题。

有没有替代jmap更快地写入heapdumps?
上述示例的特殊解决scheme也将被赞赏。

这个问题是编程和系统pipe理的混合,但是我认为我在这里是对的。

我find了我的问题的答案。 这个在serverfault上的其他问题的答案给了我这个想法。

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

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

创build核心转储比直接通过jmap创buildheapdump快得多。 通过这种方式,您可以创build一个java进程的heapdump,而不需要太长的停机时间。

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

 Error attaching to core file: Can't attach to the core file 

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

 gdb --core=[path tp core file] 

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

 Core was generated by `/opt/tomcat/bin/jsvc'.