据Oracle称,StackOverflowError是:
在发生堆栈溢出时抛出,因为应用程序过于严重.
我知道递归是什么,通常递归函数,如果没有正确终止,会导致StackOverflowError.为了检查StackOverflowError
抛出之前发生的递归调用的数量,我写了这段代码:
package ErrorCases; public class StackOverFlowError { static int i=0; void a() { //System.out.println("called "+(++i)); try{ ++i; a(); }catch(Error e) { System.out.println(e.getClass()); System.out.println(i); } } public static void main(String[] args) { new StackOverFlowError().a(); } }
在JVM抛出StackOverflowError之前,i
给出递归调用计数的值a()
.每次运行
的价值i
都不同,如:
output 1: class java.lang.StackOverflowError 10466 Output 2: class java.lang.StackOverflowError 10470
我的疑问是?
在JVM抛出之前递归有多深
StackOverflowError
?
一旦StackOverflowError
投掷,我们可以恢复吗?
Klas Lindbäc.. 6
深度取决于两件事:
1:堆栈的大小.
2:每次递归中使用的堆栈空间量.
函数参数,局部变量和返回地址都在堆栈上分配,而对象在堆上分配.
复苏
有可能恢复.
try { myDeepRecursion(); } catch (StackOverflowError e) { // We are back from deep recursion. Stack should be ok again. }
但是,请注意以下有关错误的信息(来自java API doc):
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.
编辑:
注意事项:虽然在递归函数中捕获异常是可以的,但不要试图捕获错误.如果堆栈已满,则错误处理将导致新错误.简单的事情,例如调用System.out.println()
将失败,因为堆栈上没有剩余空间用于返回地址.
这就是错误应该在递归函数之外捕获的原因.
深度取决于两件事:
1:堆栈的大小.
2:每次递归中使用的堆栈空间量.
函数参数,局部变量和返回地址都在堆栈上分配,而对象在堆上分配.
复苏
有可能恢复.
try { myDeepRecursion(); } catch (StackOverflowError e) { // We are back from deep recursion. Stack should be ok again. }
但是,请注意以下有关错误的信息(来自java API doc):
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.
编辑:
注意事项:虽然在递归函数中捕获异常是可以的,但不要试图捕获错误.如果堆栈已满,则错误处理将导致新错误.简单的事情,例如调用System.out.println()
将失败,因为堆栈上没有剩余空间用于返回地址.
这就是错误应该在递归函数之外捕获的原因.