StackOverflowError本质是单个线程调用栈被撑爆,-Xss参数控制该线程栈大小,单位支持k/m,设值需结合真实调用链深度与系统限制,盲目调大易引发线程创建失败或OOM。

StackOverflowError 本质是单个线程的调用栈被撑爆了,-Xss 就是用来控制这个“栈能有多大”的开关。它不解决递归逻辑问题,但能给合法深度留出安全空间——前提是设得合理,不是越大越好,也不是越小越省。
先搞清 -Xss 是什么、怎么写
-Xss 是 JVM 启动参数,用来指定每个线程分配的栈内存大小。单位支持 k(KB)、m(MB),比如:
- -Xss256k → 每个线程约 256 KB 栈空间
- -Xss1m → 约 1 MB,等价于 -XX:ThreadStackSize=1024
- 不设时,Linux 64 位默认通常是 1MB,Windows 32 位可能是 320KB
可以在命令行、IDE 运行配置、Tomcat 的 catalina.sh/bat 里添加,例如:java -Xss512k MyApp。
怎么判断该设多大?看真实调用链,不是拍脑袋
别一上来就设 1m 或 2m。先用 jstack <pid> 抓几次生产或压测中的活跃线程,重点看业务核心路径(比如订单计算、规则引擎、JSON 反序列化)的调用层级数。例如发现某次调用链有 78 层,每层平均占 1.1KB,再加 1.5 倍余量:78 × 1.1KB × 1.5 ≈ 129KB → 那 -Xss256k 就够用,没必要拉到 1m 白白浪费内存。
立即学习“Java免费学习笔记(深入)”;
盲目调大会挤占堆外内存,导致线程数上不去,甚至触发 OutOfMemoryError: unable to create new native thread。
按线程模型分场景选值,不是一刀切
- 传统同步 Web 容器(如 Tomcat):每请求一个线程,线程数常几百上千 → 推荐 -Xss256k~384k
- 异步框架(Netty/Vert.x/WebFlux):少量线程扛大量连接,调用链深 → 可设 -Xss1m
- Project Loom 虚拟线程:只影响 Carrier Thread,建议 -Xss128k;虚拟线程栈在堆里,不受 -Xss 约束
调完还得检查系统限制,否则 JVM 启不起来
-Xss 设再大,操作系统也得认账:
- Linux 下执行 ulimit -s,确认软限制(单位 KB)≥ 你设的 -Xss 值,否则 JVM 启动失败
- Docker/K8s 环境要算总栈内存:线程数 × -Xss,不能接近容器 memory limit,否则线程创建会静默失败
- JDK 8u291 之前启用 G1GC 时,-Xss 小于 256k 可能导致 GC 线程栈溢出
真正治本的不是调 -Xss,而是把深层递归改成显式栈+循环、加深度防护、排查 Lombok/Jackson/AOP 引起的隐式递归。-Xss 是兜底手段,不是替代方案。


















