我必须创建堆转储,这与 jmap 配合得很好。我的问题是,jmap 需要很长时间才能创建 heapdump 文件。特别是当堆变大(> 1GB)时,它会花费太长时间。
以一种情况为例:
当服务器遇到堆空间问题时,我想自动重新启动它并在重新启动之前创建一个 heapdump。这可行,但编写堆转储需要很长时间。这样服务器停机时间太长了。堆转储创建需要超过一小时。
我知道-XX:+HeapDumpOnOutOfMemoryError
,但大多数时候我可以在 jvm 抛出异常之前找到内存问题。
是否有 jmap 的替代方法可以更快地写入堆转储?
对于上述示例的特殊解决方案也将不胜感激。
这个问题是编程和系统管理之间的混合,但我认为我来对地方了。
我找到了我的问题的答案。 这个关于 serverfault 的另一个问题的答案给了我这个想法。
gdb --pid=<your java pid>
gcore <file name>
detach
quit
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 二进制文件:
要为 jmap 调用获取正确的 java 二进制文件,请使用 gdb 打开核心转储:
会有这样一行,告诉你正确的二进制文件: