4.6 使用try-finally块防止StackOverflowError时出现的问题| Java Debug 笔记

本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看<活动链接>

提问:使用try-finally块防止StackOverflowError时出现的问题

看一下下面代码的两种方法:

public static void foo() {
    try {
        foo();
    } finally {
        foo();
    }
}

public static void bar() {
    bar();
}
复制代码

bar运行会产生StackOverflowError的问题,但是foo却不会出现这个错误。(该程序似乎无限期的运行)。

问题出在哪?

回答1:

它不会永远运行。每次堆栈溢出都会导致代码移至finally块。问题在于这将需要非常,非常长的时间。时间顺序为O(2 ^ N),其中N是最大堆栈深度。

举个例子,最大深度N=5

foo() calls
    foo() calls
       foo() calls
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
       finally
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
    finally calls
       foo() calls
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
       finally
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
finally calls
    foo() calls
       foo() calls
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
       finally
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
    finally calls
       foo() calls
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
       finally
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
复制代码

要使每个级别进入finally块都需要两倍的时间,而堆栈深度可能是10,000或更大。如果您每秒可以进行10,000,000次呼叫,那么这将花费10 ^ 3003秒,甚至比宇宙存在的时间还要长。

文章翻译自Stack Overflow :stackoverflow.com/questions/1…

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享