为什么 java 递归调用函数可以 运行 永远即使 StackOverflowError?
Why java recursively calling function can run forever even though StackOverflowError?
我在 Java 考试中遇到了以下问题,为什么在递归调用函数后可以 运行 永远,即使 WhosebugError?
public class Solution {
static int i = 0;
public static void f(){
System.out.println(i++);
try {
f();
} catch (WhosebugError e) {
System.out.println(e);
f();
}
}
public static void main(String[] args) {
f();
}
}
我无法理解为什么 JVM 在我耗尽所有调用堆栈内存后仍然可以 运行? 有没有参考资料,比如JVM规范或者JVM源码,可以解释以上现象?
我既不是 java 也不是 jvm 专家,但我认为添加额外的 recursive depth
输出可以准确显示调用堆栈的情况。
public class Solution {
static int i = 0;
public static void f(int depth) {
System.out.println(i++);
System.out.println(String.format("depth=%d", ++depth));
try {
f(depth);
} catch (WhosebugError e) {
System.out.println(e);
f(depth);
}
}
public static void main(String[] args) {
f(1);
}
}
在我的测试中,典型的输出是
...more
java.lang.WhosebugError
161735
depth=3745
161736
depth=3746
161737
java.lang.WhosebugError
161738
java.lang.WhosebugError
161739
java.lang.WhosebugError
161740
depth=3744
161741
depth=3745
...more
WhosebugError
被抛出是因为 jvm 正在考虑堆栈内存的大小限制(默认为 1M?),但是异常被捕获,所以递归没有停止,它仍然尝试调用, jvm 丢弃最近的 1 或 2 个有问题的调用,然后尝试继续,因此 depth
值一次又一次地围绕相同的最大值。
我认为这样 OP 就可以毫无问题地理解为什么 i
正在增加。 我已经耗尽了调用堆栈内存 -- 你还没有,你几乎耗尽了,但是 jvm 总是清除最近的几个调用以避免耗尽。
我在 Java 考试中遇到了以下问题,为什么在递归调用函数后可以 运行 永远,即使 WhosebugError?
public class Solution {
static int i = 0;
public static void f(){
System.out.println(i++);
try {
f();
} catch (WhosebugError e) {
System.out.println(e);
f();
}
}
public static void main(String[] args) {
f();
}
}
我无法理解为什么 JVM 在我耗尽所有调用堆栈内存后仍然可以 运行? 有没有参考资料,比如JVM规范或者JVM源码,可以解释以上现象?
我既不是 java 也不是 jvm 专家,但我认为添加额外的 recursive depth
输出可以准确显示调用堆栈的情况。
public class Solution {
static int i = 0;
public static void f(int depth) {
System.out.println(i++);
System.out.println(String.format("depth=%d", ++depth));
try {
f(depth);
} catch (WhosebugError e) {
System.out.println(e);
f(depth);
}
}
public static void main(String[] args) {
f(1);
}
}
在我的测试中,典型的输出是
...more
java.lang.WhosebugError
161735
depth=3745
161736
depth=3746
161737
java.lang.WhosebugError
161738
java.lang.WhosebugError
161739
java.lang.WhosebugError
161740
depth=3744
161741
depth=3745
...more
WhosebugError
被抛出是因为 jvm 正在考虑堆栈内存的大小限制(默认为 1M?),但是异常被捕获,所以递归没有停止,它仍然尝试调用, jvm 丢弃最近的 1 或 2 个有问题的调用,然后尝试继续,因此 depth
值一次又一次地围绕相同的最大值。
我认为这样 OP 就可以毫无问题地理解为什么 i
正在增加。 我已经耗尽了调用堆栈内存 -- 你还没有,你几乎耗尽了,但是 jvm 总是清除最近的几个调用以避免耗尽。