4
public class Foo {

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

    public static void foo() {
        try {
            System.out.println("try");
            foo();
        } catch (Throwable e) {
            System.out.println("catch");
            foo();
        } finally {
                System.out.println("finally");
                foo();
        }
    }
}

谁能解释这段代码的输出?

1.eclipse(无尽)客户端模式下的输出:

    尝试
    尝试
    ……


    ...
    ...
    最后尝试
    最后尝试
    尝试
    尝试
    尝试
    最后尝试
    最后尝试
    尝试
    最后尝试
    最后尝试
    尝试
    ……
    ……

2.linux(崩溃)服务器模式下的输出:

    尝试
    尝试
    ...

    ...
    尝试
    尝试
    尝试
    尝试
    尝试
    尝试
    pc 0x00002aaaab1c53f0 和处理程序 bci -1 的缺少异常处理程序
       例外:

     编译异常表:
    ExceptionHandlerTable(大小 = 3304 字节)
    catch_pco = 700(1 个条目)
      bci -1 在范围深度 0 -> pco 11039
    catch_pco = 1736 (1 个条目)
      bci -1 在范围深度 0 -> pco 11473
    catch_pco = 1756 (1 个条目)
      bci -1 在范围深度 0 -> pco 11433
    catch_pco = 1776 (1 个条目)

4

1 回答 1

8

我想我从“Java Puzzlers”一书中记得这一点。try 块执行无限递归,这很快导致 StackOverflowError 被抛出。try 和 catch 块恢复递归,但剩余堆栈相对较小。但是,随着每个递归调用返回,剩余的堆栈再次变大......

最终结果是一个调用图,它形成了一个深度取决于堆栈大小的树;使用主流 JVM 的默认堆栈大小,树变得如此之大,以至于您必须等待十亿年才能完全遍历它并终止程序。

编辑:这就是您在客户端模式下看到的:调用图的遍历。您在服务器模式下的 Linux 上看到的要么是 JVM 错误,要么是硬件缺陷(有故障的 RAM 可能会产生这种影响)。

于 2011-07-19T09:19:17.067 回答