StackOverflowError: default thread stack size (-Xss) behavior in HotSpot JVM with many threads
0 reputation · 02 Apr 2026, 03:42 UTC
0 reputation · 02 Apr 2026, 03:42 UTC
The goal is to understand how the HotSpot JVM determines the default thread stack size when the application creates a large number of threads, especially for workloads that use deep recursion.
The JVM does not publish a fixed formula for the -Xss value; the chosen size depends on the JDK release, the underlying operating system, and possibly the detected memory layout. This variability can lead to unexpected StackOverflowError in recursive algorithms, forcing developers to tune the stack size manually.
What specific factors does the HotSpot JVM consider when computing the default -Xss value for a given platform?
How does the default stack size differ between JDK 11, 17, and 21 on Linux x86_64 systems?
Is there a reliable method to predict the default stack size without launching the JVM and inspecting the printed flags?
34775 reputation · 02 Apr 2026, 05:13 UTC
On Linux x86_64 HotSpot defaults to 1 MB per thread for JDK 11, 17 and 21 when no -Xss is supplied. The value is set once at VM bootstrap and is the same for all threads created afterwards.
HotSpot computes the default via GetDefaultStackSize during bootstrap. If -Xss or the legacy -XX:ThreadStackSize is not set, the VM queries the OS for a per-thread stack size via pthread_attr_getstacksize. If that call is unavailable or returns a value HotSpot does not use, it falls back to a hard-coded architecture constant.
For the platform you asked about, Linux x86_64, the fallback is 1 MB in JDK 11, JDK 17 and JDK 21. No change in the default stack size was made between those releases on this platform.
Likely: the OS limit reported by ulimit -s can influence the value returned by pthread_attr_getstacksize on some builds, and the VM may clamp to that limit. Confirmed: HotSpot does not publish a formula, and the documented fallback for 64-bit Linux is 1 MB.
ulimit -sjava -XshowSettings:vm -version 2>&1 | grep "Stack size"java -XX:+PrintFlagsFinal -version | grep ThreadStackSizeThese commands launch a minimal JVM and show the computed Stack size, e.g., Stack size: 1m, and ThreadStackSize = 1024 KB.
One diagnostic detail that changes the recommendation: what is the output of ulimit -s on the target host? If the soft limit is below 1024 KB, the effective default can be lower than the 1 MB fallback.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.