-XX:+HeapDumpOnOutOfMemoryError在OOM时不创建hprof文件

6
我开始我的Java代码(在Vista中使用1.6.0_16版本),其中包括以下参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=../logs。我运行代码,可以在日志中看到有两个OOM。
第一个OOM我知道是因为我可以在stdout中看到正在创建hprof文件:
java.lang.OutOfMemoryError: Java heap space
Dumping heap to ../logs\java_pid4604.hprof ...
Heap dump file created [37351818 bytes in 1.635 secs]

在代码末尾,我又遇到了OOM(内存溢出)问题,我捕获了这个异常,但是并没有生成第二个hprof文件。有人知道为什么吗?是因为我已经捕获了OOM异常吗?

2个回答

8

我不建议尝试从OutOfMemoryError中恢复,因为一些对象可能会处于未定义的状态(比如无法分配ArrayList数组来存储数据)。

关于你的问题,我怀疑-XX:+HeapDumpOnOutOfMemoryError只是有意创建单个转储以防止多个堆转储:想象一下多个线程同时抛出OOME,导致每个抛出异常都产生一个堆转储。

总之:不要尝试从OOME中恢复,并且不要期望JVM写入多个堆转储。但是,如果你仍然需要生成堆转储,可以尝试手动处理OOME异常并调用jmap来创建转储,或者使用“-XX:+HeapDumpOnCtrlBreak”(不确定如何在程序中模拟CtrlBreak)。


我知道有关不尝试从OOM中恢复的建议,但在这种情况下,我需要,必须,并且在许多情况下都有效。但是你的假设听起来很好,也许只有一个是故意创建的... 在研究此问题时,我在stackoverlfow上找到了一些问题,展示了如何通过程序创建转储,但现在找不到它了。 - Persimmonium

5

当内存不足时,仅会在第一个错误时生成一个转储文件。如果您想获取更多信息,可以尝试使用jmap或在jvm(版本6)上保持jconsole,然后在所有内容崩溃即早晨时从jconsole(或您选择的分析工具)创建自己的转储文件。

有关转储主题的更多信息,请参阅Eclipse MemoryAnalyser


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接