为什么没有OutOfMemoryError子类?

众所周知, OutOfMEmoryError有多种原因(参见第一个答案 )。 为什么只有一个exception覆盖所有这些情况而不是从OutOfMEmoryErrorinheritance的多个细粒度OutOfMEmoryError

UML

我期待,因为当发生这种情况时你真的不能做任何其他事情:因为你不管怎么说都没关系,这几乎无关紧要。 也许额外的信息会很好,但……

我知道tomcat尝试做这个“Out Of Memory Parachute”的事情,他们抓住了一大块记忆并尝试释放它,但我不确定它的效果如何。

故意非常模糊地描述垃圾收集过程,以便为JVM实现者提供尽可能大的自由。

因此,您提及的类不在API中提供,而是仅在实现中提供。

如果您依赖它们,如果在没有这些特定于供应商的子类的JVM上运行,您的程序将会崩溃,因此您不会这样做。

如果应用程序需要能够以不同方式捕获和处理不同的情况,则只需要子类化exception。 但你不应该抓住并试图从这些案件中恢复……所以不应该出现这种需要。

…但是,我仍然希望有一个更具描述性的理由让我死亡。

exception消息告诉您哪些OOME子案例已发生。 如果您抱怨消息太短暂,那么Javaexception消息的作用就不能完整解释他们报告的问题。 这就是javadocs和其他文档的用途。


@Thorbjørn提出了同样引人注目的论点。 基本上,不同的子类都是特定于实现的 。 使它们成为标准API的一部分可能会限制 JVM实现以次优方式执行以满足API要求。 当为新的特定于实现的子类创建新的子类时,这种方法可能会产生不必要的应用程序可移植性障碍。

(例如,假设的UnableToCreateNativeThreadError 1)假设线程创建因内存不足而失败,以及2)内存不足与正常的内存不足有本质区别。 2)适用于当前的Oracle JVM,但不适用于所有JVM。 1)对于当前的Oracle JVM,可能甚至都不是这样。 由于操作系统对本机线程数量施加限制,线程创建可能会失败。)


如果您对尝试从OOME恢复是一个坏主意感兴趣,请参阅以下问题:

  • 捕获java.lang.OutOfMemoryError?
  • JVM是否可以在不重新启动的情况下从OutOfMemoryError中恢复
  • 是否有可能在java中捕获内存不足? (我的答案)。

国际海事组织对这个问题没有明确的答案,这一切都归结为当时的设计决策。 这个问题非常类似于“为什么不是Date类不可变”或“为什么Properties从HashTable扩展”。 正如另一张海报所指出的,子类真的无关紧要,因为你总是搞砸了。 此外,描述性错误消息足以从故障排除措施开始。

主要是因为计算智能的东西需要在某个时刻分配内存。 因此,您必须在不进行任何计算的情况下执行OutOfMemoryException。

无论如何,这不是什么大问题,因为你的程序已经搞砸了。 您最多可以将错误返回给系统System.exit(ERROR_LEVEL); 但你甚至无法记录,因为它需要分配内存或使用可能搞砸的内存。

这是因为所有4个都是无法恢复的致命错误(除了堆空间之外,但仍然会在故障点的边缘附近)