【问题标题】:java out of memory then exitjava内存不足然后退出
【发布时间】:2011-05-17 06:42:01
【问题描述】:

我有一个必须分析大文件的软件。限制输入或提供无限内存不是一种选择,所以我不得不忍受飞行的 OOME。因为 OOME 只杀死线程,所以我的软件运行在一些糟糕的状态。

从外部看起来一切正常,因为该过程正在运行,但在内部它是脑死的。

我想拔掉它的插头。但是我该怎么做呢?

捕获 OOME 并不能保证将执行下一行代码。例如 System.exit(9)。所以JVM必须注意OOME并破坏自己。

他们有一些虚拟机选项吗?

【问题讨论】:

  • “捕获 OOME 并不能保证下一行代码将被执行。” 你有这方面的参考吗?

标签: java memory jvm out-of-memory exit


【解决方案1】:

当您获得 OOME 时,您的内存可能会非常低,并且日志记录并不总是有效。解决此问题的一种方法是使用一种关闭方法,该方法保存一些在关闭之前不会释放的内存。

例如

 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);
     }
  }

【讨论】:

  • 有趣的方法!你在某处生产吗?
  • 勇敢、异国情调、令人发指:p
  • @JoachimSauer 我确实在生产中使用了它,并保留了 64KB。
【解决方案2】:

因此 JVM 必须注意到 OOME 并自行销毁。他们是否为此提供了一些 vm 选项?

没有。

但是,我不得不质疑您无法捕获 OutOfMemoryError 并立即在异常处理程序中调用 System.exit() 的假设。

在实践中它应该可以工作。唯一的潜在问题是,如果您调用了 Runtime.setRunFinalizersOnExit(true) ...,如果您以非零退出状态退出,那么即使调用也会被忽略。

(关于捕获 OOME 和其他随机 Error 异常的警告是 JVM 可能不处于适合状态继续执行。但调用 System.exit(nonzero) 不会这样做!)

【讨论】:

  • 它确实有效,我编写了一个 Swing 程序,它捕获 OutOfMemoryError 然后在屏幕上显示一条关于它的消息。
  • 在调用堆栈的下几级捕获 OOME 的行为可能为一些基本的日志记录/错误处理释放了足够的内存(因为调用堆栈中的 GC 根消失了)。
  • 确实如此,@Peter Lawrey 的回答是另一种方法。 (我在其他情况下也看到过。例如,一些 JVM 会做这种事情来为创建 OOME 及其堆栈帧保留空间。)
【解决方案3】:

您可以使用-XX:+ExitOnOutOfMemoryError - Java 8 update 92 支持。

您还可以使用-XX:+CrashOnOutOfMemoryError 获取核心转储以进行进一步调查。

您还可以使用-XX:+HeapDumpOnOutOfMemoryError 在 OOME 上生成堆转储以供进一步调查。

来源:thisthis

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 2013-10-23
    • 2012-06-21
    • 2013-09-10
    • 2012-12-12
    • 2017-07-19
    • 1970-01-01
    相关资源
    最近更新 更多