Java 捕获OutOfMemoryError是一个坏主意吗?
可能重复:Java 捕获OutOfMemoryError是一个坏主意吗?,java,try-catch,out-of-memory,Java,Try Catch,Out Of Memory,可能重复: 它们是: Java虚拟机无法分配对象时引发,因为 内存不足,服务器无法提供更多内存 垃圾收集器 爪哇说: 错误是Throwable的一个子类,表示存在严重问题 一个合理的应用程序不应该试图抓住。大多数这样的 错误是异常情况 这感觉就像是在听: 如果你快要淹死了,要讲道理:你不应该试图往上游 让你的头露出水面。死亡通常是由于 异常情况 让我们设想一个场景,其中一个人正在运行一个服务。由于某些原因,同一服务器上的另一个应用程序正在占用大量内存,从而导致您的服务出现意外OOM。试图减少此
它们是: Java虚拟机无法分配对象时引发,因为 内存不足,服务器无法提供更多内存 垃圾收集器 爪哇说: 错误是Throwable的一个子类,表示存在严重问题 一个合理的应用程序不应该试图抓住。大多数这样的 错误是异常情况 这感觉就像是在听: 如果你快要淹死了,要讲道理:你不应该试图往上游 让你的头露出水面。死亡通常是由于 异常情况 让我们设想一个场景,其中一个人正在运行一个服务。由于某些原因,同一服务器上的另一个应用程序正在占用大量内存,从而导致您的服务出现意外OOM。试图减少此服务的内存消耗以保持用户可用性是否是一个坏主意
或者,在抛出OOM之后,JVM级别是否发生了更根本的事情,阻止了此类解决方案的实现?这里的问题是,OOM是一个在正常情况下不应该发生的错误。通过捕获它并尝试释放内存,您可能会掩盖其他地方的某种泄漏或意外行为 如果您确实得到OOM,可能是因为您没有将JVM配置为使用更多内存。 Java虚拟机无法分配对象时引发,因为 内存不足,服务器无法提供更多内存 垃圾收集器 在那一点上,你就完蛋了。这种描述意味着Java/JVM无法获得足够的资源来运行,如果这是真的,那么执行更多的Java代码来修复问题本身就是有问题的 一个很好的类比是,你的车已经没油了,你想通过踩油门来解决这个问题 更好的解决方案是进行容量规划并确保 1) 您的服务器有足够的内存执行其工作
2) 在您的服务器上运行的服务在规范范围内运行,不会消耗超过一定数量的资源。这是个坏主意。主要是因为
OutOfMemoryError
是一个错误
而不是一个异常
-错误“表示合理的应用程序不应试图捕捉的严重问题。”
相反,请分析可能出现的情况,并根据本文提供的信息应用修复程序。这是没有用的。因为在捕捉到错误的那一刻,您可能缺少堆内存,任何新对象创建都可能抛出新的OOME。在捕获过程中有如此小的机动余地意味着你唯一能采取的行动就是退出 测试此代码段,并告诉我您的输出是什么:
import java.util.LinkedList;
import java.util.List;
public class OOMErrorTest {
public static void main(String[] args) {
List<Long> ll = new LinkedList<Long>();
try {
long l = 0;
while(true){
ll.add(new Long(l++));
}
} catch(OutOfMemoryError oome){
System.out.println("Error catched!!");
System.out.println("size:" +ll.size());
}
System.out.println("Test finished");
}
}
import java.util.LinkedList;
导入java.util.List;
公共类OOMErrorTest{
公共静态void main(字符串[]args){
List ll=新的LinkedList();
试一试{
长l=0;
while(true){
ll.add(新长(l++);
}
}捕获(OutOfMemoryErrorOome){
System.out.println(“错误捕获!!”;
System.out.println(“大小:+ll.size());
}
System.out.println(“测试完成”);
}
}
但严格地说,是的,这些是可以捕捉到的。你不能真正从OOM中恢复过来 然而,有一个原因让我们尝试捕捉任何东西,那就是当我们在一个我不再参与的项目中完全做到这一点时,“可丢弃的捕捉”派告诉我的,那就是一个原因:尝试记录发生的事情。因为如果你不知道发生了什么,就很难弄清楚如何让软件恢复运行 还有一个很大的“但是”原因:它通常不起作用
错误通常无法从您运行的代码中修复,这就是为什么会有这种差异。@aix我可以通过将某些数据结构的引用设置为null来减少对它们的引用,即使我没有正确保存它们,但在戏剧性的情况下仍然可以。@dogbane您的引用并没有回答我的问题,这个问题不是重复的。一个更好的类比是:你驾驶一辆着火的汽车。不要试图继续并到达目的地。靠边站。如果你的服务人员在发出OOM后可以选择使用更少的内存,那么为什么不总是使用更少的内存来永远不发出OOM呢?@JVerstry在这种情况下,飞机正机头潜入大西洋,而你离水面只有100米,两个引擎都出现故障。你对此无能为力。让它沉下去!“JVM不再正常运行”或没有资源正常运行?第二,编辑了我的答案。这也是我的想法,因此,尝试(至少)挽救这一天并非完全不可能或不合理。是的。你的油箱是空的。你需要加更多的汽油,而不是踩油门,但是如果你能修复飞机飞行以避免坠机呢?有什么理由不这样做吗?这就是我的问题…老兄,真是个比喻!因此,飞机失事是由于某些情况造成的,而这些情况大部分时间是人类无法控制的。为此,制定了应急程序,以便仍有一些灵魂能够获救。类似地,如果应用程序如此关键,那么它应该有早期警告,并且应该有一个恢复过程(如果合理的话)。如果您想要捕捉
OutOfMemoryError
您会在哪里捕捉到这些信息?大多数时候,当你抓住它时,你对此无能为力。就像一架飞机在大西洋中部坠毁一样;即使你有降落伞,存活的机会也是一致的,但我可以在释放内存并亲自呼叫gc后记录这个问题。这不是不可能的,如果