如何可靠地使用Java堆转储?


9

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

我们是否可以采取任何措施来提高获得干净堆转储的可能性,以解决内存问题?我已经读到jmap在Java 1.4中存在主要问题,但是现在应该主要解决这些问题。


4
我将此问题提名为“最无意的听起来令人作呕”。
phoebus

1
哈哈-我想过要故意让它听起来令人作呕,但我是新来的,我不确定社区如何接受它:)。
karlcyr

Answers:


7

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

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

gcore是* nix实用程序,用于生成正在运行的程序的映像。见链接


在Linux上用gdb尝试了一下,效果很好。
基督教徒

哪个JDK具有“ gcore”?我的,用于Linux 1.6.0.20的Sun 32位jdk没有它。
djangofan 2011年

编辑与gcore澄清。
fglez 2011年

2

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

更多信息在这里。


2

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


谢谢克里斯蒂安-在抛出错误之前jmap更可能可靠吗?
karlcyr

jmap仍然需要一些时间才能获得堆转储。但是只要您的jvm / tomcat主要负责,您将获得完整的heapdump。
基督教徒

我认为最干净,最简单的工具就是“ Visual VM”。它可能超出范围,但是为VisualVM创建一个自定义插件来检测情况并从VisualVm中进行自动转储将非常棒,恕我直言。
djangofan

2

感谢大家的建议。

我们最后要做的是编写一个脚本来主动监视垃圾收集日志。根据我们的经验,背靠背Full GC几乎总是在OOM之前,因此我们的脚本会检测到此事件,从负载平衡池中优雅地删除服务器,并强制进行堆转储。这大大提高了我们的效率。


2

这是一个相当老的问题,但我会回答,希望有人会觉得这很有用。

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

您也可以尝试通过gdb进行核心转储。拥有核心后,jmap可以将核心转换为堆转储。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.