rel*_*ood 11 java out-of-memory java-8
有没有办法OutOfMemoryError为我的Java应用程序构建全局侦听器?
我想try-catch在OOM上优雅地停止JVM(不是一个选项).
Jig*_*shi 14
您可以使用JVM选项
-XX:OnOutOfMemoryError="<cmd args>; <cmd args>"
Run Code Online (Sandbox Code Playgroud)
并执行您选择的命令
由于OutOfMemoryError通常不会被捕获,因此最简单的方法之一就是
Thread.setDefaultUncaughtExceptionHandler((thread,t) -> {
if(t instanceof OutOfMemoryError) {
System.exit(1);
}
});
Run Code Online (Sandbox Code Playgroud)
但在某些情况下,就像通过a执行的操作一样ExecutorService,所有throwable都会被自动捕获.尽管如此,在这些情况下,应用程序中应该有一些代码可以评估结果并处理特殊情况.
但也许,你想在它迟到之前作出反应,例如在没有足够的内存来保存未决数据之前.解决方案将进入以下方向:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,当总堆使用率超过阈值时,无法简单地接收通知,因此,我们必须在支持它的每个内存池(通常是终身代)上安装阈值,并重新检查通知的总使用情况,在总使用量超过阈值时触发关闭.
还有一个ExitOnOutOfMemoryError选项用作JVM命令行选项。
-XX:OnOutOfMemoryError
Run Code Online (Sandbox Code Playgroud)
ExitOnOutOfMemoryError-启用此选项时,JVM会在第一次出现内存不足错误时退出。如果您希望重新启动JVM实例而不是处理内存不足错误,则可以使用它。
这实际上不是正常的 JVM退出,我认为关闭挂钩不会运行。
| 归档时间: |
|
| 查看次数: |
2212 次 |
| 最近记录: |