aio*_*obe 2 java out-of-memory
这是一个后续问题,当没有足够的内存来抛出OutOfMemoryError时会发生什么?
我的问题如下:如果a OutOfMemoryError是预分配的(为了避免OutOfMemoryError对象的内存不足的情况)并且JVM必须抛出这种类型的错误两次或更多次,那么预分配对象如何真实地实现该getStackTrace方法?
如果重用同一个对象,那么其中一个对象很可能会失效getStackTrace,不是吗?
答案的关键在于合同Throwable.getStackTrace():
在某些情况下,某些虚拟机可能会从堆栈跟踪中省略一个或多个堆栈帧.在极端情况下,允许没有关于此throwable的堆栈跟踪信息的虚拟机从此方法返回零长度数组.
该OutOfMemoryError抛出其实并不一定是预分配一个.如果它有足够的内存来分配一个OutOfMemoryError具有适当堆栈跟踪的新内存,它将会.但如果它没有内存,它将使用预分配的没有堆栈跟踪信息.因此,如果需要抛出另一个预先分配的对象,则可以重新使用这种预分配对象OutOfMemoryError.
修改 您提到的问题的(最佳)答案解释了正在发生的事情:
private static void test(OutOfMemoryError o) {
try {
for (int n = 1; true; n += n) {
int[] foo = new int[n];
}
} catch (OutOfMemoryError e) {
System.out.println("Stack trace length=" + e.getStackTrace().length +
", object id=" + System.identityHashCode(e));
if (e == o)
System.out.println("Got the same OutOfMemoryError twice (abort)");
else
test(e);
}
}
public static void main (String[] args) {
test(null);
}
Run Code Online (Sandbox Code Playgroud)
输出:
Stack trace length=2, object id=1743911840
Stack trace length=3, object id=2136955031
Stack trace length=4, object id=903470137
Stack trace length=5, object id=1607576787
Stack trace length=0, object id=2103957824 <--- new object cannot be allocated
Stack trace length=0, object id=2103957824 <--- same object reused
Got the same OutOfMemoryError twice (abort)
Run Code Online (Sandbox Code Playgroud)