Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何侦听OutOfMemoryError并退出JVM_Java_Java 8_Out Of Memory - Fatal编程技术网

Java 如何侦听OutOfMemoryError并退出JVM

Java 如何侦听OutOfMemoryError并退出JVM,java,java-8,out-of-memory,Java,Java 8,Out Of Memory,有没有办法为我的Java应用程序构建一个全局OutOfMemoryError监听器 我想在OOM上优雅地停止JVM(try catch不是一个选项)。您可以使用 -XX:OnOutOfMemoryError=“;” 并执行您选择的命令由于通常不会捕获OutOfMemoryError,最简单的方法之一是 Thread.setDefaultUncaughtExceptionHandler((thread,t) -> { if(t instanceof OutOfMemoryError

有没有办法为我的Java应用程序构建一个全局
OutOfMemoryError
监听器

我想在OOM上优雅地停止JVM(
try catch
不是一个选项)。

您可以使用

-XX:OnOutOfMemoryError=“;”

并执行您选择的命令

由于通常不会捕获
OutOfMemoryError
,最简单的方法之一是

Thread.setDefaultUncaughtExceptionHandler((thread,t) -> {
    if(t instanceof OutOfMemoryError) {
        System.exit(1);
    }
});
但在某些情况下,如通过
ExecutorService
执行的操作,所有可丢弃的内容都会被自动捕获。不过,在这些情况下,应用程序中应该有一些代码来评估结果并处理异常情况

但是,您可能希望在延迟之前做出反应,例如,在内存不足之前保存挂起的数据。解决方案将朝以下方向发展:

MemoryMXBean mBean = ManagementFactory.getMemoryMXBean();
((NotificationEmitter)mBean).addNotificationListener(
    (n, mb) -> {
        MemoryUsage mu = ((MemoryMXBean)mb).getHeapMemoryUsage();
        if(mu.getUsed()*100/mu.getMax() > 80)
            System.out.println("more than 80% used");// may initiate a shut down
    },
    n -> n.getType().equals(MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED),
    mBean);

for(MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
    if(pool.getType() == MemoryType.HEAP && pool.isCollectionUsageThresholdSupported()) {
        pool.setCollectionUsageThreshold((int)Math.floor(pool.getUsage().getMax()*0.8));
    }
}
不幸的是,当堆的总使用率超过阈值时,无法简单地接收通知,因此,我们必须在支持它的每个内存池上安装一个阈值(通常是终身生成),并在通知时重新检查总使用率,当总使用量超过阈值时触发关机。

还有用作JVM命令行选项的

-XX:OnOutOfMemoryError
ExitOnOutOfMemoryError—启用此选项时,JVM将在第一次出现内存不足错误时退出。如果您希望重新启动JVM实例而不是处理内存不足错误,可以使用它


这并不是一个真正优雅的JVM退出,我不认为关机挂钩会运行。

我想你会发现JVM在OOM错误时自动退出。你是否试图利用熔毁攻击?实际上我的应用程序没有在OOM上停止,这就是我来这里寻求帮助的原因:)如果你的应用程序没有在OOM上停止,你(或库)正在捕获它(并且可能打印一些消息,或者你不知道)。添加一些关于你实际问题的细节,也许有一个解决方案你所说的“优雅地停止JVM”是什么意思?
OutOfMemoryError
,一个
错误
,表示您无法合理处理的严重问题。但是您可以在它关闭之前执行一些操作。我们有一个类似的工具,当VM达到一定的堆百分比时,会杀死它们并启动新的VM,我不知道这是如何做到的,谢谢您的提示
-XX:OnOutOfMemoryError