Java 如何侦听OutOfMemoryError并退出JVM
有没有办法为我的Java应用程序构建一个全局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
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