如果JVM堆已满,并且所有对象都是强引用,那么现在,如果您将创建一个新对象,那么将会发生什么以及将在哪个内存中创建该对象。 (不会出现OOM错误)
答案 0 :(得分:3)
如果没有足够的可用空间,则JVM将运行垃圾收集器(通常是“完整” GC)。如果运行GC后 still 可用空间不足,则试图new
对象的线程将抛出OutOfMemoryError
异常。
将堆栈展开到捕获点 可能会使足够的对象无法访问,从而JVM能够继续(在另一个GC之后)。但是,当发生OOME时,恢复代码通常无法确定或消除可能已经发生的损坏。例如对象创建不正确,其他线程可能已因OOME而死亡。
从OOMEs恢复通常是有问题的,是否应该尝试还存在争议:
答案 1 :(得分:1)
根据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 Test class java.lang.OutOfMemoryError, false