我知道每个对象都需要堆内存,而堆栈上的每个原语/引用都需要堆栈内存。
当我尝试在堆上创建一个对象并且没有足够的内存来执行此操作时,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 节指出:
- If Java virtual machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java virtual machine stack for a new thread, the Java virtual machine throws an
OutOfMemoryError
.
对于堆,第 3.5.3 节。
- If a computation requires more heap than can be made available by the automatic storage management system, the Java virtual machine throws an
OutOfMemoryError
.
因此,它在分配对象之前会提前进行计算。
发生的情况是 JVM 尝试为内存中称为永久代区域(或 PermSpace)的对象分配内存。如果分配失败(即使在 JVM 调用垃圾收集器尝试分配可用空间之后),它也会抛出 OutOfMemoryError
。即使是异常也需要内存空间,所以会无限期抛出错误。
Further reading. ?此外,OutOfMemoryError
可能出现在不同的JVM structure. 中。
关于java - 当内存不足引发 OutOfMemoryError 时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9261705/