7

在 OutOfMemoryError 之后,JVM 会自行终止吗?如果不是那为什么?它会尝试取回资源吗?还是有其他原因?

4

5 回答 5

12

OutOfMemoryError 不会终止 JVM。

如果它未被捕获,它将终止引发错误的线程。其他线程继续运行得很好,除非它们当然也会导致 OutOfMemoryErrors。

只有在所有线程都已终止或所有剩余线程都是守护线程之后,JVM 才会终止。

它不会终止 JVM,因为它不必这样做。终止JVM是一个非常极端的操作,并不是轻而易举的。

它不会尝试取回任何资源,因为没有任何东西可以检索。抛出OOME的原因仅仅是:JVM无法获取资源,因为所有资源都被占用了。它已经做了它所能做的一切。

必须记住,OOME不一定是在消耗内存最多的线程中抛出的。一个线程可以消耗所有内存并将处理交给另一个尝试分配“仅一个字节”的线程。Thas 当然会失败,并且尝试分配一个字节的线程会被 OOME 中断。这就是为什么从 OOME 中恢复几乎是不可能的原因。

于 2012-04-26T06:16:38.433 回答
4

JVM 终止,如果(与任何其他异常或错误一样)它没有在任何地方被捕获并且没有其他线程是守护线程。

它不会立即终止,因为OutOfMemoryError可以捕获并且应用程序可以尝试进行一些错误处理,从仅记录错误到关闭该计算并以其他方式正常继续。

后者在发生错误时被认为是有风险的,但通常可能没有任何问题,因为许多对象可能会超出抛出点和捕获点之间的范围OutOfMemoryError,然后可以通过垃圾收集释放这些对象以提供编程新的内存来使用。如果OutOfMemoryError发生这种情况是因为一个特定的计算需要比可用内存更多的内存,并且应用程序随后执行了其他操作,那很好。

于 2012-04-26T06:07:06.050 回答
1

这取决于您是否处理该错误。如果你不这样做,那么应用程序和当前线程将被终止。如果这个线程恰好是最后一个运行的线程(在大多数情况下是当前应用程序的主线程),JVM 也会退出(尽管在退出之前它可能仍会进行一些日志记录、创建内存转储等)。

如果您处理错误,您通常只需在停止 JVM 之前尝试进行一些清理。在大多数情况下,尝试从OutOfMemoryError. 有关更多详细信息,请参阅此处:JVM 可以从 OutOfMemoryError 中恢复而无需重新启动

于 2012-04-26T06:06:32.580 回答
0

它不会自行终止,它只是抛出一个错误,说它无法创建更多对象,因为内存不可用,尽管您可以通过处理错误继续代码,但您必须仅使用当前创建的对象生存,或者可能是释放或取消您不再需要的那些。

PS:但它不是处理此类错误并继续的推荐方法

于 2012-04-26T06:06:36.487 回答
0

通常,JVM 仅在最后一个非守护线程退出时终止。抛出 OutOfMemoryError 或任何其他类型的错误或异常可能会导致最后一个非守护线程存在,如果它没有被捕获。

但是,如果错误被捕获并且没有重新抛出,或者有另一个非守护线程正在运行,则 JVM 不会退出。也就是说,导致程序退出的任何特定错误都没有什么特别之处。

有两个资格

  • System.exit() 将导致 JVM 开始关闭并且无法被捕获。拥有多个线程没有区别。
  • ThreadDeath 错误的特殊之处在于默认情况下不会打印。否则,它的行为就像任何其他错误一样。
于 2012-04-26T07:17:59.893 回答