gpt4 book ai didi

java - 如果抛出两次,预分配的 OutOfMemoryError 如何真实地实现 Throwable.getStackTrace?

转载 作者:行者123 更新时间:2023-11-30 06:31:44 25 4
gpt4 key购买 nike

这是对 What happens when there's insufficient memory to throw an OutOfMemoryError? 的后续问题

我的问题如下:如果预先分配了一个OutOfMemoryError(以避免OutOfMemoryError对象内存不足的情况)并且JVM必须抛出这个类型错误两次或更多次,那么预分配对象如何如实执行getStackTrace方法?

如果重复使用同一个对象,那么其中一个对象很可能会有无效的 getStackTrace,不是吗?

最佳答案

答案的关键在于 Throwable.getStackTrace() 的契约(Contract):

Some virtual machines may, under some circumstances, omit one or more stack frames from the stack trace. In the extreme case, a virtual machine that has no stack trace information concerning this throwable is permitted to return a zero-length array from this method.

抛出的 OutOfMemoryError 实际上不一定是预分配的。如果它有足够的内存来分配一个新的 OutOfMemoryError,它会使用适当的堆栈跟踪。但是,如果它没有内存,它将使用一个预分配的内存,其中没有堆栈跟踪信息。因此,如果需要抛出另一个 OutOfMemoryError,则可以重用这样的预分配对象。


修改 the (best) answer对你提到的问题解释了发生了什么:

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);
}

输出:

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)

关于java - 如果抛出两次,预分配的 OutOfMemoryError 如何真实地实现 Throwable.getStackTrace?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9545807/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com