我必须创建 heapdump,它与 jmap 配合得很好。我的问题是,jmap 创建 heapdump 文件需要很长时间。特别是当堆越来越大(> 1GB)时,它花费的时间太长了。
举个例子:
当服务器的堆空间出现问题时,我想自动重启它并在重启之前创建一个堆转储。这可行,但写入堆转储的时间太长。这样服务器停机时间太长。创建堆转储需要一个多小时。
我知道-XX:+HeapDumpOnOutOfMemoryError
,但大多数时候我可以在 jvm 抛出异常之前发现内存问题。
有没有可以代替 jmap 更快地写入堆转储的替代方案?如果能
为上述示例提供特殊解决方案,我们将不胜感激。
这个问题是编程和系统管理的混合,但我认为我在这里处于正确的位置。
答案1
我找到了我的问题的答案。 这对 serverfault 上的另一个问题的回答给了我这个想法。
- 使用 gdb 连接到你的 java 进程
gdb --pid=<your java pid>
- 从 gdb 创建核心转储
gcore <file name>
detach
quit - 重新启动 Java 进程或做任何你喜欢的事情
- 通过将 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
为了获取 jmap 调用的正确 java 二进制文件,请使用 gdb 打开核心转储:
gdb --core=[path tp core file]
将会有一行这样的内容,告诉你正确的二进制文件:
Core was generated by `/opt/tomcat/bin/jsvc'.