【问题标题】:What is the maximum depth of the java call stack?java调用栈的最大深度是多少?
【发布时间】:2011-06-11 16:05:59
【问题描述】:

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

【问题讨论】:

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

标签: java


【解决方案1】:

这取决于分配给堆栈的虚拟内存量。

http://www.odi.ch/weblog/posting.php?posting=411

您可以使用-Xss VM 参数或@987654322@ 构造函数进行调整。

【讨论】:

  • 也许你要放置的堆栈帧的大小?
  • 限制还取决于函数中的堆栈使用情况。
  • 如果我们不提Xss,那么呢?
【解决方案2】:

我在我的系统上测试并没有发现任何常量值,有时会在 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();
    }

}

【讨论】:

  • 这不是尾递归,不应该溢出吗?编辑:对不起。在 Java 中,它在 8027 处崩溃;在我感到无聊之前,在 Scala 中它达到了 8594755。
  • @arya JVM 语义的一个重要部分是不支持尾递归。这给那些想要在 JVM 上实现尾递归语言的人带来了很多有趣的问题。
  • public foo() { try { foo(); } finally { foo(); } } 可以永远“虚拟”运行,但只能在 java 中运行。
  • 对我来说,StackOverflowError 出现在 8792 之后
  • @ThorbjørnRavnAndersen 尾递归 优化 不受支持。很明显,您可以进行尾递归。它只是没有优化它以不增加调用堆栈。
【解决方案3】:

可以使用-Xss 命令行开关设置堆栈大小,但根据经验,它足够深,即使不是数千次调用也足够深。 (默认值取决于平台,但在大多数平台上至少为 256k。)

如果您遇到堆栈溢出,99% 的情况是由代码中的错误引起的。

【讨论】:

  • 第二段+1。人们应该永远记住这一点。
  • 使用eclipse,我只得到1024个递归调用。
  • @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) {作为唯一的方法。

【讨论】:

    猜你喜欢
    • 2019-03-14
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多