11

如果OutOfMemoryError非常不鼓励捕获 an,因为在捕获错误后您可能不知道 JVM 的状况,为什么 JVM 不简单地终止并以某种方式通知用户而不是抛出错误?

4

5 回答 5

5

因为没有向用户报告错误情况的单一标准方法。抛出错误允许在顶层捕获对象,并且在终止之前报告条件可能是适当的(控制台消息,写入日志文件,显示对话框等)。该文档指出,合理的应用程序不应捕获错误,这是真的:处理它们的最佳方法是在框架代码中,因为它们的处理方式几乎没有(尽管不是零)变化。具体来说,它们实际上无法从 中恢复,这就是大多数应用程序作者试图捕捉它们的原因。

更新:还有另一个原因。抛出错误不仅可以捕获错误:它还会导致“finally”块中的代码被执行。由于这些块可能包含关键的清理代码,因此在应用程序终止之前允许它们运行非常重要。

于 2013-08-30T20:21:23.513 回答
4

因为你可以知道该做什么以及如何去做。

示例:您的代码(尝试)创建一个包含数千万个元素的数组(取决于某些输入)。任何OutOfMemoryException人很可能都是出于这个原因。特别是,您只能将数组创建放在 try/catch 块中。在异常之后,内存很可能处于相当不错的水平(数组要么完全分配,要么根本没有分配)。您的程序可以继续执行。甚至生成错误消息、发送电子邮件或采取任何其他纠正措施并继续下一个输入(来自用户、批次等)。

这种劝阻说明通常针对初学者/普通开发人员。一种会尝试在程序的顶层捕获异常的方法,例如,没有关于触发它的详细信息。

于 2013-08-30T20:30:16.070 回答
1

在应用程序未终止的情况下,您有机会转储数据,或通过其他方式确定 OOME 的原因。

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

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

-XX:OnOutOfMemoryError="kill -9 %p"

于 2013-08-30T20:05:09.363 回答
1

Throwables (Exceptions, Errors) 是 JVM 通知用户问题的标准方式。这不是抓​​住它,而是记录发生的事情,地点和时间。在OOM之后创建一些方法来执行逻辑并不是确定的事情,因为JVM状态可能不一致,并且通知逻辑可能永远不会执行。

此外,作为补充操作,您还可以请求 OOM 错误生成转储,您可以稍后查看(使用转储分析器)并搜索应用程序中的内存泄漏,使用

-XX:+HeapDumpOnOutOfMemoryError

于 2013-08-30T20:10:25.673 回答
0

通过抛出 OutOfMemoryError,某个地方可能有足够的内存来接收异常并记录它发生的事实(例如记录器或标准输出)。然后程序可能应该退出,而不是尝试在可能无效的状态下继续。

尽管这种记录/记录 OutOfMemoryError 的尝试可能会因为系统内存不足而失败,但它也很有可能成功。如果JVM在OOM上立即退出,那么记录问题原因的可能性为零。记录问题的非零机会优于记录问题的零机会。

于 2013-08-30T20:44:24.213 回答