为什么JVM不会简单地终止而不是抛出OOME?

时间:2013-08-30 20:00:11

标签: java

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

5 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:1)

您有可能转储数据,或在应用程序未终止时以其他方式确定OOME的原因。

如果未捕获,则终止发起错误的THREAD。其他线程保持正常运行,除非它们当然也会导致OutOfMemoryErrors。

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

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

答案 3 :(得分:1)

Throwables(异常,错误)是JVM通知用户有关问题的标准方法。它不是捕捉它的东西,而是记录发生的事情,地点和时间。在OOM之后创建一些执行逻辑的方法并不确定,因为JVM状态可能不一致,并且通知逻辑可能永远不会被执行。

此外,作为补充操作,您还可以请求OOM错误生成转储,您可以稍后查看(使用转储分析器)并使用

在应用程序中搜索内存泄漏

-XX:+HeapDumpOnOutOfMemoryError

答案 4 :(得分:0)

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

虽然这种记录/记录OutOfMemoryError的尝试可能会失败,因为系统内存不足,但它很可能会成功。如果JVM在OOM上即时退出,则记录问题的可能性为零。记录问题的非零概率优于记录问题的零概率。