如果JVM Heap内存已满,并且您正在尝试创建一个新对象,将会发生什么



如果jvm堆已满,并且所有对象都是强引用,现在,如果您将创建一个新对象,那么将会发生什么以及在哪个内存中创建对象。(没想到OOM错误)

如果没有足够的可用空间,JVM将运行垃圾收集器(通常是"完整" GC)。如果运行GC后仍然没有足够的可用空间,则试图new的线程将抛出OutOfMemoryError异常。

  • 如果OOME在主线程上并且未捕获,JVM将退出。
  • 如果抓住了OOME或未将其扔到"主"线程上,JVM将尝试进行。

将堆栈放松到捕获点 May 使足够的对象无法到达以使JVM能够继续(在另一GC之后)。但是,当发生OOME时,恢复代码通常无法确定或撤消可能发生的损害;例如未正确创建的对象,可能死于OOME的其他线程。

从OOMES恢复通常是有问题的,是否应该尝试:

是有争议的:
  • 您可能无法正确恢复。应用程序/服务器/任何可能最终处于破损状态。
  • 如果OOME的原因是内存泄漏,则可能以增加频率重复出现。申请可以死亡并重新启动。
  • 如果OOME的原因是JVM的内存太小或任务太大,则恢复并尝试重新尝试。

按JLS:

如果对类实例创建表达式的评估发现无法执行创建操作的内存不足,则抛出了OutOfMemoryError。在评估任何参数表达式之前,就会发生此检查。

它甚至为您提供了一个示例程序,该程序将抛出OOM ...最终:

class List {
    int value;
    List next;
    static List head = new List(0);
    List(int n) { value = n; next = head; head = this; }
}
class Test {
    public static void main(String[] args) {
        int id = 0, oldid = 0;
        try {
            for (;;) {
                ++id;
                new List(oldid = id);
            }
        } catch (Error e) {
            List.head = null;
            System.out.println(e.getClass() + ", " + (oldid==id));
        }
    }
}

在我的系统上,花了几分钟,但最终到达那里:

$ javac test.java$ Java测试java.lang.outofmemoryerror,false

相关内容

最新更新