堆栈大小验证和StackOverflowError

时间:2015-07-16 21:39:55

标签: java stack stack-size

在Java中,每个线程都会分配一些堆栈内存,由-Xss参数定义,并且有一些默认值。

现在,我通过在代码下面运行java -Xss1k Test来覆盖默认堆栈大小。

上次输出:

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

问题:

  • 为什么值打印到18479?我期待的值远远少于因为我提到的堆栈大小为1KB并且在每个堆栈帧上存储了一个int。
  • 使用1KB或1024字节的堆栈大小,只能存储256(1024/4)个int值。没有?因为每次递归调用都会添加一个堆栈帧,并且int将存储在其中。因此,只要添加了256个大小为4字节的堆栈帧,就应该有StackOverflowError。
  • 我的理解是全局作用域counter不会以任何方式对堆栈消耗做出贡献,因为它将存在于旧的gen空间中。确认?


 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();
    }
}

1 个答案:

答案 0 :(得分:1)

  

使用1KB或1024字节的堆栈大小,只能存储256(1024/4)个int值。没有?

没有。返回地址也存储在堆栈中,因此您应该在少于256个递归调用中溢出。

  

我的理解是全局作用域x不会以任何方式对堆栈消耗做出贡献,因为它将存在于旧的gen空间中。确认?

确认。

对于Windows:

  

请注意,在某些版本的Windows上,操作系统可能会使用非常粗略的粒度来舍入线程堆栈大小。如果请求的大小小于默认大小1K或更多,则堆栈大小向上舍入为默认值;否则,堆栈大小向上舍入为1 MB的倍数

Source