我有一个必须分析大文件的软件。限制输入或提供无限的内存不是一种选择,所以我必须忍受飞行的OOME。因为OOME只杀死了线程,所以我的软件运行起来很糟糕。
从外面来看,一切看起来都不错,因为这个过程正在运行,但内部则是脑力不足。
我想拔掉插头。但是我怎么能这样做呢?
捕获OOME并不保证下一行代码将被执行。例如System.exit(9)。因此,JVM必须注意到OOME和自己的存在。
他们有一些vm选项吗?
答案 0 :(得分:8)
当你得到一个OOME时,你的内存可能非常低,而且日志记录并不总是有效。解决这个问题的一种方法是使用一个关闭方法来保存一些在关闭之前不会释放的内存。
e.g。
private static byte[] lastResort = new byte[256*1024];
public static void handleOOME(OutOfMemoryError oome) {
lastResort = null;
try {
LOG.fatal("Dying after ", oome);
} finally {
System.exit(-1);
}
}
答案 1 :(得分:2)
因此JVM必须注意到OOME并自行销毁。他们有一些vm选项吗?
没有。
但是,我必须质疑您的假设,即您无法捕获OutOfMemoryError
并立即在异常处理程序中调用System.exit()
。
在实践中应该有效。唯一可能的问题是,如果您调用Runtime.setRunFinalizersOnExit(true)
...如果以非零退出状态退出,则会被忽略。
(关于捕获OOME和其他随机Error
异常的警告是JVM可能不处于适合状态以继续执行。但是调用System.exit(nonzero)
不是这样做!)
答案 2 :(得分:1)