当没有足够的内存抛出OutOfMemoryError时会发生什么?

问题:

我知道每个对象都需要堆内存,堆栈上的每个原语/引用都需要堆栈内存。
当我尝试在堆上创建一个对象,内存不足时,JVM会在堆上创建一个java.lang.OutOfMemoryError并将其抛出给我。
所以隐含的,这意味着启动时有一些JVM保留的内存。
当这个保留的内存被用尽时,会发生什么(它一定会用尽,阅读下面的讨论),而JVM没有足够的内存来创建一个java.lang.OutOfMemoryError的实例
它挂了吗或者他会给我一个null,因为没有记忆new一个OOM的实例?

try {
    Object o = new Object();
    // and operations which require memory (well.. that's like everything)
} catch (java.lang.OutOfMemoryError e) {
    // JVM had insufficient memory to create an instance of java.lang.OutOfMemoryError to throw to us
    // what next? hangs here, stuck forever?
    // or would the machine decide to throw us a "null" ? (since it doesn't have memory to throw us anything more useful than a null)
    e.printStackTrace(); // e.printStackTrace() requires memory too.. =X
}

==
 为什么JVM不能保留足够的内存?
无论保留多少内存,如果JVM没有办法“回收”该内存,那么该内存仍然可能被使用:

try {
    Object o = new Object();
} catch (java.lang.OutOfMemoryError e) {
    // JVM had 100 units of "spare memory". 1 is used to create this OOM.
    try {
        e.printStackTrace();
    } catch (java.lang.OutOfMemoryError e2) {
        // JVM had 99 units of "spare memory". 1 is used to create this OOM.
        try {
            e.printStackTrace();
        } catch (java.lang.OutOfMemoryError e3) {
            // JVM had 98 units of "spare memory". 1 is used to create this OOM.
            try {
                e.printStackTrace();
            } catch (java.lang.OutOfMemoryError e4) {
                // JVM had 97 units of "spare memory". 1 is used to create this OOM.
                try {
                    e.printStackTrace();
                } catch (java.lang.OutOfMemoryError e5) {
                    // JVM had 96 units of "spare memory". 1 is used to create this OOM.
                    try {
                        e.printStackTrace();
                    } catch (java.lang.OutOfMemoryError e6) {
                        // JVM had 95 units of "spare memory". 1 is used to create this OOM.
                        e.printStackTrace();
                        //........the JVM can't have infinite reserved memory, he's going to run out in the end
                    }
                }
            }
        }
    }
}

或更简洁:

private void OnOOM(java.lang.OutOfMemoryError e) {
    try {
        e.printStackTrace();
    } catch (java.lang.OutOfMemoryError e2) {
        OnOOM(e2);
    }
}

回答:

JVM从来没有真正耗尽内存。它提前进行堆栈的内存计算。
Structure of the JVM, Chapter 3,第3.5.2节规定:

对于,第3.5.3节。

因此,在进行对象分配之前,它会提前进行计算。
发生什么是JVM尝试为名为永久生成区域(或PermSpace)的内存中的对象分配内存。如果分配失败(甚至在JVM调用垃圾收集器尝试分配可用空间之后),它会抛出一个OutOfMemoryError。即使异常需要一个内存空间,所以错误将被无限期地抛出。
 Further reading.?此外,OutOfMemoryError可以发生在不同的JVM structure.

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: What happens when there’s insufficient memory to throw an OutOfMemoryError?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

+ 62 = 66