捕获OutOfMemoryError是一个坏主意吗?

时间:2011-09-08 16:13:44

标签: java try-catch out-of-memory

  

可能重复:
  Catching java.lang.OutOfMemoryError

OutOfMemoryError是:

  

当Java虚拟机无法分配对象时抛出,因为   内存不足,没有更多的内存可供使用   垃圾收集器

Java说:

  

错误是Throwable的子类,表示严重问题   一个合理的应用程序不应该试图抓住。最多的   错误是异常情况。

这听起来像听到:

  

如果你溺水,那就合理:你不应该试着向上游泳   保持头脑清醒。死亡通常是由于   异常情况。

让我们想象一个人正在运行服务的场景。出于某种原因,同一服务器上的另一个应用程序正在占用大量内存,从而导致服务中出现意外的OOM。尝试减少此服务的内存消耗以保持用户可用是不是一个坏主意?

或者是否在JVM级别发生了更为根本的事情,导致在抛出OOM后阻止执行此类解决方案?

5 个答案:

答案 0 :(得分:3)

正如你引用的那样

  

当Java虚拟机无法分配对象时抛出,因为   内存不足,没有更多的内存可供使用   垃圾收集器

那时你被搞砸了。该描述暗示Java / JVM无法获得足够的资源来运行,如果这是真的,执行更多Java代码来解决问题本身就会有问题。

一个很好的类比是你的汽车已经没油了,你想通过踩油门来解决这个问题。

更好的解决方案是进行容量规划并确保

1)您的服务器有足够的内存来完成工作 2)服务器上运行的服务在规范内执行,并且不会消耗超过一定数量的资源。

答案 1 :(得分:0)

这里的问题是OOM是一个错误,在正常情况下不应该发生。通过捕获并尝试释放内存,您可能会在其他地方掩盖某种泄漏或意外行为。

如果您确实获得了OOM,可能是因为您没有将JVM配置为使用更多内存。

答案 2 :(得分:-1)

这是一个坏主意。主要是因为OutOfMemoryErrorError而不是Exception - “错误”表示合理的应用程序不应该试图抓住的严重问题。“

相反,请根据此PDF

中提供的信息分析您的可能方案并应用修补程序

答案 3 :(得分:-1)

没用。因为在捕获错误的那一刻,您可能缺少堆内存,因此任何新对象创建都可能抛出新的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");
        }

      }

但严格来说,是的,这些都是可以捕获的。

答案 4 :(得分:-1)

你无法从OOM中恢复过来。

然而,有一个原因可以尝试抓住任何东西 - 当我们在一个我不再工作的项目中做到这一点时,这就是“可抛出的”派系告诉我的 - 一个原因是:尝试记录发生的事情。因为如果你不知道发生了什么,很难弄清楚如何恢复和运行软件。

还有一个很大的“但是”这个原因:它通常不起作用。

错误通常无法从正在运行的代码中修复,这就是存在差异的原因。