Try-finallyブロックはStackOverflowErrorを防ぎます 質問する

Try-finallyブロックはStackOverflowErrorを防ぎます 質問する

次の 2 つの方法をご覧ください。

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

public static void bar() {
    bar();
}

を実行するbar()と明らかに になりますStackOverflowErrorが、 を実行するfoo()と になりません (プログラムは単に無期限に実行されるように見えます)。なぜでしょうか?

ベストアンサー1

永久に実行されるわけではありません。スタック オーバーフローが発生するたびに、コードは finally ブロックに移動します。問題は、非常に長い時間がかかることです。時間のオーダーは O(2^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 ブロックに組み込むには 2 倍の時間がかかり、スタックの深さは 10,000 以上になる可能性があります。1 秒あたり 10,000,000 回の呼び出しを実行できる場合、これには 10^3003 秒、つまり宇宙の年齢よりも長い時間がかかります。

おすすめ記事