抛出 OOM 异常时无法使用 VM 选项获取转储文件:HeapDumpOnOutOfMemoryError

Posted

技术标签:

【中文标题】抛出 OOM 异常时无法使用 VM 选项获取转储文件:HeapDumpOnOutOfMemoryError【英文标题】:can't get a dump file using VM Option :HeapDumpOnOutOfMemoryError when OOM exception thrown 【发布时间】:2017-07-10 21:41:39 【问题描述】:

首先,我使用 Intelli Idea 作为 IDE 来运行旨在导致 OOM Exception 的应用程序。 虚拟机选项: -Xmx20M -XX:MaxDirectMemorySize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\chao.zhang1\Desktop\aaa.hprof

应用: 导入 sun.misc.Unsafe;

import java.lang.reflect.Field;
public class DirectMemoryOOM
    private static final int _1MB=1024*1024;
    public static void main(String[]args)throws Exception
        Field unsafeField=Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe=(Unsafe)unsafeField.get(null);
        while(true)
            unsafe.allocateMemory(_1MB);
        
    

抛出异常后,目录'C:\Users\chao.zhang1\Desktop\'中不存在转储文件。

其次,我尝试了另一种方法来避免IDE的影响,我在cmd命令行中运行这个命令: java DirectMemoryOOM -Xmx20M -XX:MaxDirectMemorySize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\chao.zhang1\Desktop\aaa.hprof 仍然没有创建转储文件。

登录控制台是:

Exception in thread "main" java.lang.OutOfMemoryError
        at sun.misc.Unsafe.allocateMemory(Native Method)
        at DirectMemoryOOM.main(DirectMemoryOOM.java:12)

2017 年 2 月 23 日更新: 今天又遇到一个jvm崩溃,intelli idea控制台输出:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (javaCalls.cpp:62), pid=11864, tid=13164
#  guarantee(thread->is_Java_thread()) failed: crucial check - the VM thread cannot and must not escape to Java code
#
# JRE version: Java(TM) SE Runtime Environment (7.0_79-b15) (build 1.7.0_79-b15)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.79-b02 mixed mode windows-amd64 compressed oops)
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# E:\apache-tomcat-7.0.69\apache-tomcat-7.0.69\bin\hs_err_pid11864.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
Disconnected from the target VM, address: '127.0.0.1:58121', transport: 'socket'

我想知道“无法写入核心转储”是否与此有关。 Windows 的客户端版本默认不启用 Minidumps,是否可能是 windows 系统没有正确配置转储文件。 我还尝试通过高级系统设置->启动和恢复->设置->选择“小内存转储”来启用迷你转储。但什么都没有改变。 谁能给点建设性的建议?谢谢!

【问题讨论】:

今天我遇到了 jvm 崩溃: 设置 HeapDumpOnOutOfMemoryError 标志仅在 OutOfMemoryError 的原因是堆空间不足时才导致写入堆转储。在其他情况下,如果堆不在内存泄漏的位置,则转储堆没有多大意义。 这个问题也很好。提示:您不要将此类解决方案放入评论中。有两种选择:如果您认为这是一个非常特殊的问题;然后考虑删除问题。但是,如果您认为您的问题+您的解决方案可能对其他人有所帮助;写下你的自己的答案。接受这个答案甚至是合法的。 【参考方案1】:

事实证明,我没有按正确的顺序放置 JVM 选项。错误的版本是 :java DirectMemoryOOM -Xmx20M -XX:MaxDirectMemorySize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\chao.zhang1\Desktop\aaa.hprof ,这是不正确的,因为我们需要把JVM选项像这样的应用程序类:java -Xmx20M -XX:MaxDirectMemorySize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\chao.zhang1\Desktop\aaa.hprof DirectMemoryOOM

【讨论】:

【参考方案2】:

您在系统设置中启用的是小型转储,以防蓝屏,即在内核模式下发生异常时。这与Java无关。

如果您想要 Java 客户端版本的小型转储,请将 -XX:+CreateMinidumpOnCrash 添加到您的命令行。

【讨论】:

感谢您的所有回答。事实证明,我没有按正确的顺序放置 JVM 选项。错误的版本是 :java DirectMemoryOOM -Xmx20M -XX:MaxDirectMemorySize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\chao.zhang1\Desktop\aaa.hprof ,这是不正确的,因为我们需要把JVM选项像这样的应用程序类:java -Xmx20M -XX:MaxDirectMemorySize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\chao.zhang1\Desktop\aaa.hprof DirectMemoryOOM

以上是关于抛出 OOM 异常时无法使用 VM 选项获取转储文件:HeapDumpOnOutOfMemoryError的主要内容,如果未能解决你的问题,请参考以下文章

Objectmapper writeValueAsString 抛出 OOM 异常

JVM虚拟机本地方法栈抛出stackoverflowerror和oom的异常的示例

java——OOM内存泄漏

有没有办法在不抛出异常的情况下转储堆栈跟踪?

图片oom问题

将自定义数据包含到 iOS 故障转储中