Java - 关闭内存不足错误

dje*_*lin 47 java out-of-memory

关于如何最好地处理这个问题,我听到了非常矛盾的事情,并且陷入了以下两难境地:

  • OOME带来了一个线程,但不是整个应用程序
  • 我需要关闭整个应用程序,但不能因为线程没有任何内存

我一直都知道最好的做法就是让它们离开以便JVM可以死掉,因为JVM在那时处于不一致的状态,但这似乎不适用于此.

Tom*_*icz 51

OutOfMemoryError就像任何其他错误一样.如果它从它逃脱Thread.run()将导致线程死亡.而已.此外,当线程死亡时,它不再是GC根,因此仅由此线程保留的所有引用都有资格进行垃圾回收.这意味着JVM很可能从OOME恢复.

如果你想要杀死你的JVM,不管是因为你怀疑它可能处于不一致状态,请将其添加到你的java选项中:

-XX:OnOutOfMemoryError="kill -9 %p"
Run Code Online (Sandbox Code Playgroud)

%p是当前的Java进程PID占位符.其余的是自我解释.

当然,您也可以尝试OutOfMemoryError以某种方式捕捉和处理它.但这很棘手.

  • 警告:突然终止-9可能会在您的日志刷新之前取消进程,因此它可能看起来像崩溃而没有指示发生了什么.明智的做法是使用一系列命令来尝试礼貌关闭"stop.sh%p",其中你的停止脚本可以记录它即将杀死进程然后尝试"kill -TERM $ 1",然后睡觉,然后做最后杀了-9.这样你就不会遇到神秘的崩溃,当你的jvm自杀而没有记录它在主日志之前做的事情. (16认同)

ahu*_*ahu 31

对于版本8u92,Oracle JDK中现在有一个JVM选项,可以在发生OutOfMemoryError时退出JVM:

发行说明:

ExitOnOutOfMemoryError - 启用此选项时,JVM会在第一次出现内存不足错误时退出.如果您更喜欢重新启动JVM实例而不是处理内存不足错误,则可以使用它.

  • 不幸的是,这仅适用于堆耗尽的“实际” OutOfMemoryExceptions。如果由于本机线程耗尽而发生错误,则不会触发ExitOnOutOfMemoryError。参见https://bugs.openjdk.java.net/browse/JDK-8155004 (3认同)

fla*_*nze 30

在Java版本8u92中的VM参数

  • -XX:+ExitOnOutOfMemoryError
  • -XX:+CrashOnOutOfMemoryError

添加了,请参阅发行说明.

ExitOnOutOfMemoryError
启用此选项时,JVM会在第一次出现内存不足错误时退出.如果您更喜欢重新启动JVM实例而不是处理内存不足错误,则可以使用它.

CrashOnOutOfMemoryError
如果启用此选项,则在发生内存不足错误时,JVM会崩溃并生成文本和二进制崩溃文件.

增强请求:JDK-8138745(参数命名错误,但 JDK-8154713,ExitOnOutOfMemoryError而不是ExitOnOutOfMemory)

  • 不幸的是,这只适用于堆耗尽的“真正的”OutOfMemoryExceptions。如果由于本机线程耗尽而发生错误,则不会触发 ExitOnOutOfMemoryError 和 CrashOnOutOfMemoryError。请参阅https://bugs.openjdk.java.net/browse/JDK-8155004 (4认同)

Mar*_*mer 5

如果您想关闭您的程序,请查看命令行上的-XX:OnOutOfMemoryError="<cmd args>;<cmd args>"此处记录的)选项。只需将其指向应用程序的终止脚本即可。

一般来说,我从来没有运气在不重新启动应用程序的情况下优雅地处理这个错误。总会有一些角落案例溜过,所以我个人建议确实停止您的应用程序,但调查问题的根源。


dan*_*dan 5

一旦错误发生,您可以强制程序以多种方式终止.像其他人建议的那样,如果需要,您可以捕获错误并在此之后执行System.exit.但我建议您也使用-XX:+ HeapDumpOnOutOfMemoryError,这样JVM将在生成事件后使用应用程序的内容创建内存转储文件.您将使用配置文件,我建议您使用Eclipse MAT来调查图像.通过这种方式,您可以快速找到问题的原因,并做出正确的反应.如果您不使用Eclipse,则可以将Eclipse MAT用作独立产品,请参阅:http://wiki.eclipse.org/index.php/MemoryAnalyzer.