如何可靠地获取 Java 堆转储?

如何可靠地获取 Java 堆转储?

我的团队在尝试获取由 OutOfMemoryErrors 触发的良好堆转储时遇到了困难。由于特定原因,我们目前使用从 bash 脚本调用的 jmap 来获取转储,而不是使用 HeapDumpOnOutOfMemoryError 标志。我们使用的是 64 位 1.6 JVM,堆大小约为 3 GB。我们的堆转储有 90% 的时间会失败(估计)。

我们可以做些什么来提高获得干净的堆转储的几率,以便用于解决内存问题?我了解到 jmap 在 Java 1.4 中存在重大问题,但这些问题现在应该大部分都得到了解决。

答案1

您的操作系统是什么?(我无法添加评论)。

对于 Solaris,我们首先强制核心转储(gcore <pid>),然后将 jmap 附加到核心转储文件(jmap -heap:format=b <path to java bin> <path to core>)可以获得更好的结果

gcore是一个 *nix 实用程序,用于生成正在运行的程序的映像。请参阅关联

答案2

我们有一个 JSP,它查询 ManagementFactory.getThreadMXBean() 并生成报告。当应用程序崩溃时可能没什么用,但如果你每隔一分钟左右轮询一次,你就会知道发生了什么。

更多信息请点击此处。

答案3

您可以从外部通过 jmx 监控您的应用程序。当您知道一些表明即将出现 OutOfMemory 的指标时,您可以在引发异常之前触发 jmap 运行。

答案4

这是一个相当老的问题,但我会回答,希望有人会发现它有用。

jmap 有一个 -F 选项(强制)。过去事实证明,这个选项对我来说效果不佳。如果您要使用 -F 选项,我建议您还将 java.io.tmp 目录指定为 jmap 命令的一部分。JVM 版本 1.6.22 存在一个问题,由于临时目录设置,jmap 实用程序无法正常工作。

您还可以尝试通过 gdb 进行核心转储。一旦获得核心,jmap 就可以将核心转换为堆转储。

相关内容