是否有任何意义在Java中捕获内存不足错误(java.lang.OutOfMemoryError
)?
答案 0 :(得分:11)
是即可。以下是一些有意义的例子:
然而,请注意,通常情况下(除非您处于一次分配大量内存的位置),您可能不会特别针对这些情况捕获OutOfMemoryError,而是在主入口点的顶部一直catch Throwable
。
答案 1 :(得分:11)
黄金法则只是捕捉您可以处理的错误。如果您在OutOfMemory错误后可以做一些有用的事情,那么请继续。
答案 2 :(得分:7)
不,抓住Exception
和RuntimeException
,但几乎没有(从'永远'改变)Error
:
错误是
Throwable
的子类 这表明严重的问题 a 合理的申请不应该尝试 赶上。大多数此类错误都是 异常情况。ThreadDeath
错误,虽然是“正常”的条件,但是 也是Error
的子类,因为大多数 应用程序不应该尝试捕获 它
注意:强>
我在这里引用官方的Javadocs。如果您不同意,请告诉Oracle,不要拍摄信使: - )
答案 3 :(得分:5)
正如其他一些答案所指出的那样,抓住OutOfMemoryError
并尝试恢复 1 是一个糟糕的主意。而不是仅仅重复javadoc说你Error
异常是不可恢复的,我会试着解释原因。
事实上,至少有两个可靠的理由说明OOME的恢复是不明智的:
第一个原因是OOME通常是 未确诊内存泄漏的结果。如果您的应用程序捕获并尝试恢复,则泄漏的内存仍然可以访问,因此仍然无法回收。因此,当您的应用程序开始执行操作时,可能会泄漏更多内存...并遇到另一个OOME。应用程序迟早会停止运行。
由于无法确定您的应用程序不会泄漏,因此OOME恢复永远不会是一个可靠,可靠的答案。
第二个原因是当OOME发生时,它可能会对执行状态造成损害。它可能导致线程终止,让其他线程等待永远不会到达的通知等。它可能发生在更新关键应用程序数据结构或(可能更糟)JVM数据结构的过程中。如果您的应用程序然后尝试恢复,它可能会锁定,或者(更糟)它可能会继续使用损坏的数据,并产生不可预测的结果。
除非您对代码库进行取证分析,否则您永远不能完全确定不会发生此类事情。
我不会说你永远不应该试图从OOME中恢复,但总的来说这是一件冒险的事情。而且应用程序越复杂,评估风险就越困难。
1 - 我在这里谈论捕获OOME以试图允许应用程序像以前一样继续运行;即恢复申请。捕获OOME以执行(或触发)有序关闭是另一回事。
答案 4 :(得分:2)
如果您希望正常关闭以特定处理此情况。
如果您可能需要分配大型阵列并且希望正常降级系统,也可以使用它。
编辑:我用来检查OOM是否存在流损坏的代码示例。我已经替换了len检查以确保len在0到16 MB之间。
DataInputStream dis = new DataInputStream(socket.getInputStream());
public byte[] readBytes() {
int len = dis.readInt();
try {
byte[] bytes = new byte[len];
dis.readFully(bytes);
return bytes;
} catch(OutOfMemoryError e) {
log.error("Corrupt stream of len="+len);
closeSocket();
return null;
}
}
答案 5 :(得分:2)
这已经多次被提及,但是回复表明有些人对OutOfMemoryError
的这种(常见)恢复技术感到困惑。查看我的帖子What if new fails?,了解如何操作。
答案 6 :(得分:1)
我唯一做过的就是移动开发。您可以要求用户关闭其他应用程序,以使您的应用程序能够正常工作。但这不是Android开发的情况。
我没有看到你可以对这种情况做任何其他事情。可能是,一些适当的记录或清理。
答案 7 :(得分:1)
这不是例外;这是一个错误:java.lang.OutOfMemoryError
你可以从Throwable下降时抓住它:
尝试{
//在这里创建大量对象并将它们存放在某处
} catch(OutOfMemoryError E){
//释放一些(所有)上述对象
}
但是,除非你做了一些相当具体的事情(比如在特定的代码部分中分配大量的东西),否则你可能无法抓住它,因为你不知道它会被扔到哪里从
答案 8 :(得分:1)
这是你永远不应该抓住的错误之一。原因很简单,你无法在运行时对它做任何事情。但是,如果您的应用程序经常遇到此错误,那么您应该考虑以下策略来缓解此问题 -
-Xms1024m -Xmx1024m
如果错误仍然存在,那么请使用JProfiler或Eclipse MAT等分析器来分析应用程序使用的内存量。
转移到64位系统并进一步增加JVM内存。