Java 堆栈深度和 -Xss:疯狂的结果

问题描述

我已经对 -Xss 参数以及允许您显式配置堆栈深度的 constructor of Thread 进行了以下测试(尽管文档很清楚这只是一个提示,没有例外即使 JVM 决定完全忽略此参数也会抛出)。

当我运行它时,我得到疯狂的结果。不同的值取决于我何时运行它(大概那时,热点正在启动,热点变体以某种方式需要更少的堆栈空间?为什么?),有时,更大堆栈给我更少 允许的深度,这没有任何意义。

一些结果:

操作系统 JDK -Xss 选项 类型 最大深度
Mac OS Big Sur 采用OpenJDK8 160k 主线程优先 1693
Mac OS Big Sur 采用OpenJDK8 20 万 主线程优先 2635
Mac OS Big Sur 采用OpenJDK8 40 万 主线程优先 8592
Mac OS Big Sur 采用OpenJDK8 160k 主线程秒+ 4233
Mac OS Big Sur 采用OpenJDK8 20 万 主线程秒+ 6793
Mac OS Big Sur 采用OpenJDK8 40 万 主线程秒+ 19593
Mac OS Big Sur 采用OpenJDK14 144k 主线程优先 1268
Mac OS Big Sur 采用OpenJDK14 15 万 主线程优先 12500
Mac OS Big Sur 采用OpenJDK14 160k 主线程优先 1952
Mac OS Big Sur 采用OpenJDK14 20 万 主线程优先 2733
Mac OS Big Sur 采用OpenJDK14 40 万 主线程优先 7762
Mac OS Big Sur 采用OpenJDK14 140k 主线程秒+ 2963
Mac OS Big Sur 采用OpenJDK14 15 万 主线程第二 10936
Mac OS Big Sur 采用OpenJDK14 15 万 主线程第三+ 26515
Mac OS Big Sur 采用OpenJDK14 160k 主线程秒+ 3987
Mac OS Big Sur 采用OpenJDK14 20 万 主线程秒+ 6547
Mac OS Big Sur 采用OpenJDK14 40 万 主线程秒+ 19347
Mac OS Big Sur 采用OpenJDK14 任何 具有显式 600k 的线程 32151
Mac OS Big Sur 采用OpenJDK14 任何 显式 2MB 的线程 49999

OpenJDK 项目自己的 JDK16-ea 版本与 aojdk14 的编号几乎相同。

当我使用 -Xss150k发生了什么,为什么这给了我比 144k(最小值)或 160k 更深的深度?

为什么允许在运行之间更改堆栈深度?

测试代码设置:

> cat Test.java
public class Test {
        private static String title;
        public static void main(String[] args) throws Exception {
                Runnable r = () -> {
                        System.out.printf("[%12s] Allowed stack depth: %d\n",title,measure());
                };
                title = "Main1";
                r.run();
                title = "Main2";
                r.run();
                title = "Thread 600KB";
                Thread t = new Thread(Thread.currentThread().getThreadGroup(),r,"test",600L * 1024L);
                t.start();
                t.join();
                title = "Main3";
                r.run();
                title = "Thread 2MB";
                t = new Thread(Thread.currentThread().getThreadGroup(),2L * 1024L * 1024L);
                t.start();
                t.join();
                title = "Main4";
                r.run();
        }

        public static int measure() {
                int min = 1;
                int max = 50000;
                while (min < max) {
                        int mid = (max + min) / 2;
                        try {
                                attempt(mid);
                                if (min == mid) return min;
                                min = mid;
                        } catch (StackOverflowError e) {
                                max = mid;
                        }
                }
                return min;
        }

        public static void attempt(int depth) {
                if (depth == 0) return;
                attempt(depth - 1);
        }
}
> $JAVA16HOME/bin/javac Test.java; $JAVA16HOME/bin/java -Xss150k Test
[       Main1] Allowed stack depth: 18749
[       Main2] Allowed stack depth: 26517
[Thread 600KB] Allowed stack depth: 32155
[       Main3] Allowed stack depth: 26517
[  Thread 2MB] Allowed stack depth: 49999
[       Main4] Allowed stack depth: 26517

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)