1

在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不会以任何方式对堆栈消耗做出贡献,因为它将存在于旧代空间中。确认?


 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 上,操作系统可能会使用非常粗略的粒度对线程堆栈大小进行四舍五入。如果请求的大小比默认大小小 1K 或更多,则堆栈大小向上舍入到默认值;否则,堆栈大小向上舍入为 1 MB 的倍数

来源

于 2015-07-16T21:44:02.403 回答