1

Java では、各スレッドには、パラメータで定義されたスタック メモリが割り当てられ、-Xssデフォルト値があります。

ここで、以下のコードを として実行して、デフォルトのスタック サイズをオーバーライドしましたjava -Xss1k Test

最後の出力:

18479
18480Exception in thread "main" java.lang.StackOverflowError

質問:

  • 18479 までの値が出力されるのはなぜですか? 1KB のスタック サイズについて言及し、各スタック フレームに int を格納していたため、はるかに少ない値を期待していました。
  • 1KB または 1024 バイトのスタック サイズでは、256 (1024/4) 個の int 値しか保存できませんでした。いいえ?再帰呼び出しごとに 1 つのスタック フレームが追加され、int がそこに格納されるためです。したがって、それぞれ 4 バイトのサイズを持つ 256 個のスタック フレームが追加されるとすぐに、StackOverflowError が発生するはずです。
  • 私の理解では、グローバル スコープcounterは古い世代空間に存在するため、スタックの消費にはまったく寄与しません。確認?


 public class Test {
    private static int counter = 0;
    public static void main(String[] args) {
        getMeStackOverflowException();
    }

    private static void getMeStackOverflowException(){
        int x = 123;
        System.out.println(Test.counter++);
        getMeStackOverflowException();
    }
}
4

1 に答える 1

1

1KB または 1024 バイトのスタック サイズでは、256 (1024/4) 個の int 値しか保存できませんでした。いいえ?

いいえ。戻りアドレスもスタックに格納されるため、256 回未満の再帰呼び出しでオーバーフローする必要があります。

私の理解では、グローバル スコープの x は、古い世代空間に存在するため、スタックの消費にはまったく寄与しません。確認?

確認済み。

Windows の場合:

Windows の一部のバージョンでは、OS が非常に粗い粒度を使用してスレッド スタック サイズを切り上げる場合があることに注意してください。要求されたサイズがデフォルト サイズよりも 1K 以上小さい場合、スタック サイズはデフォルトに切り上げられます。それ以外の場合、スタック サイズは 1 MB の倍数に切り上げられます。

ソース

于 2015-07-16T21:44:02.403 に答える