为什么较大的 Xss 不能提供更大的最大堆栈深度?

问题描述 投票:0回答:1

首先,代码:

public class StackSOF {
    private int deep = 0;
    public void stackLeak() {
        deep++;
        stackLeak();
    }    
    public static void main(String[] args) {
        StackSOF sof = new StackSOF();        
        try {
            sof.stackLeak();
        } catch (Throwable e) {
            System.out.println(" stack deep = " + sof.deep + "\n\r" + e);
        }
    }
}

在 macOS 10.15.2 上,11.0.5+10 来自 AdoptOpenJDK。

$ java -Xint -Xss159k StackSOF
 stack deep = 4422
java.lang.StackOverflowError
$ java -Xint -Xss160k StackSOF
 stack deep = 668
java.lang.StackOverflowError
$ java -Xint -Xss161k StackSOF
 stack deep = 4422
java.lang.StackOverflowError

为什么最大堆栈深度160k小于159k?

macos jvm jvm-hotspot
1个回答
3
投票

我认为这是需要纠正的不正确行为。我已经提交了错误JDK-8236569

事实证明,

-Xss
不是 4K 的倍数根本无法在 macOS 上运行。

-Xss
参数被处理两次。第一个(主)线程的堆栈大小由启动器配置。启动器简单地调用
pthread_attr_setstacksize
而不预处理参数。

但是,

pthread_attr_setstacksize
的 Mac OS X 文档明确指出,如果
EINVAL
不是系统页面大小的倍数,则该函数返回
stacksize
。此行为与 Linux 不同,其中
pthread_attr_setstacksize
可能接受奇数值。

-Xss
也由 JVM 处理,在这种情况下,该值将 rounded 为页面大小:

  // Make the stack size a multiple of the page size so that
  // the yellow/red zones can be guarded.
  JavaThread::set_stack_size_at_create(align_up(stack_size_in_bytes, vm_page_size()));

因此,新线程将正确调整堆栈大小。如果您将测试代码更改为在新线程中运行,它将按预期运行。

public class StackSOF {
    private int deep = 0;
    public void stackLeak() {
        deep++;
        stackLeak();
    }    
    public static void main(String[] args) {
        new Thread(() -> {
            StackSOF sof = new StackSOF();
            try {
                sof.stackLeak();
            } catch (Throwable e) {
                System.out.println(" stack deep = " + sof.deep + "\n\r" + e);
            }
        }).start();
    }
}

尽管由于四舍五入,159k 和 160k 之间不会有差异:

$ java -Xint -Xss159k StackSOF
 stack deep = 666
java.lang.StackOverflowError
$ java -Xint -Xss160k StackSOF
 stack deep = 666
java.lang.StackOverflowError
$ java -Xint -Xss161k StackSOF
 stack deep = 708
java.lang.StackOverflowError
© www.soinside.com 2019 - 2024. All rights reserved.