java调用堆栈的最大深度是多少?


100

在收到StackOverflowError之前,我需要进入调用堆栈多深?答案平台是否依赖?



由于这是一个很好的问题,因此我将标题更新为我认为与含义更清楚相关的内容。(例如,以前我认为您可能是指在运行时捕获的特定堆栈的深度)。如果您不同意,请随时将其更改。
Andrzej Doyle

Answers:



31

我在系统上进行了测试,没有找到任何常量值,有时在8900次调用后出现堆栈溢出,有时仅在7700次随机数之后才发生。

public class MainClass {

    private static long depth=0L;

    public static void main(String[] args){
        deep(); 
    }

    private static void deep(){
        System.err.println(++depth);
        deep();
    }

}

15
是不是尾递归并且永远不应该溢出?编辑:对不起。在Java中,它在8027时崩溃了;在Scala中,在我感到无聊之前,它达到了8594755。
阿里亚

9
@arya JVM语义的重要组成部分是不支持尾递归。对于那些想在JVM上实现尾递归的语言的人来说,这带来了很多有趣的问题。
托尔比约恩Ravn的安徒生

2
public foo() { try { foo(); } finally { foo(); } }只能在Java中永久“虚拟地”运行。
Felype 2015年

对我来说,StackOverflowError发生在8792之后
ericdemo07

2
不支持@ThorbjørnRavnAndersen尾递归优化。显然,您可以进行尾递归。它只是没有对其进行优化而不增加调用堆栈。
苗条的

19

堆栈大小可以通过-Xss命令行开关设置,但是根据经验,它足够深,可以进行数百甚至数千个调用。(默认值取决于平台,但在大多数平台中至少为256k。)

如果出现堆栈溢出,则99%的时间是由代码错误引起的。


3
+1为第二段。人们应该永远记住这一点。
mcveat 2011年

6
使用eclipse,我只能得到1024个递归调用。
2013年

2
@Norswap您是根据堆栈跟踪的大小确定的吗?不管堆栈的实际大小如何,该值似乎都限制为1024。
布赖恩·麦卡顿

4

比较这两个调用:
(1)静态方法:

public static void main(String[] args) {
    int i = 14400; 
    while(true){   
        int myResult = testRecursion(i);
        System.out.println(myResult);
        i++;
    }
}

public static int testRecursion(int number) {
    if (number == 1) {
        return 1;
    } else {
        int result = 1 + testRecursion(number - 1);
        return result;
    }    
}
 //Exception in thread "main" java.lang.StackOverflowError after 62844

(2)使用不同类的非静态方法:

public static void main(String[] args) {
    int i = 14400;
    while(true){       
        TestRecursion tr = new TestRecursion ();
        int myResult = tr.testRecursion(i);
        System.out.println(myResult);
        i++;
    }
} 
//Exception in thread "main" java.lang.StackOverflowError after 14002

测试递归类具有public int testRecursion(int number) {作为唯一方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.