StackOverflow 經典討論:JVM 最大線程數非固定值,取決於 OS 進程虛擬記憶體限制、JVM 堆/非堆配置、線程棧大小 (-Xss)、CPU 核心數。本文綜合多位專家回答與實測數據,給出估算公式與調優建議。
MaxThreads ≈ (MaxProcessMemory - JVMMemory - OSReserved) / ThreadStackSize
// 32 位 Linux/Windows: 進程用戶空間 2~3 GB
// 64 位: 理論極大,受限於物理記憶體+Swap
// ThreadStackSize 預設: Linux 64位 1024KB, Windows 32位 320KB, 可用 -Xss256k 減小
| 環境 | 堆大小 (-Xmx) | 最大線程數 | 備註 |
|---|---|---|---|
| OS X 10.5, Java 5, 32位 | 默認 | ~2,550 | 拋 OutOfMemoryError: unable to create new native thread |
| Vista x64, JDK 1.6, -Xss 默認 | 2 MB | 5,744 | |
| 同上 | 1024 MB | 2,583 | 堆越大,留給線程棧的虛擬記憶體越少,線程數反而下降 |
| Linux 32位, -Xss128k | 512 MB | ~13,000 | Neil Coffey 實測 |
| Windows Server, 64位, 16GB RAM | 4 GB | ~30,000+ | 受限於物理記憶體與 Swap |
32 位進程虛擬地址空間固定(~2-3GB)。堆佔用的記憶體區域與線程棧區域共享同一虛擬地址空間。增大 -Xmx 會壓縮可分配給線程棧的連續地址範圍,導致 pthread_create/CreateThread 失敗。結論:需創建大量線程時,適當減小 -Xmx 並設置較小 -Xss(如 256k/128k)。
ThreadPoolExecutor)、非阻塞 I/O(Netty/NIO)、虛擬線程(Java 21+ Thread.ofVirtual())。-Xss256k 或 -Xss128k(簡單任務足夠),避免棧溢出(StackOverflowError)。jcmd VM.info 查看 ThreadStackSize;Prometheus + JMX Exporter 監控 jvm_threads_live、jvm_threads_daemon。ulimit -u (max user processes)、/proc/sys/kernel/pid_max、/etc/security/limits.conf (nofile/nproc)。Thread.startVirtualThread(() -> ...) 或 Executors.newVirtualThreadPerTaskExecutor()。虛擬線程由 JDK 調度,不佔用 OS 線程,棧在堆上動態增減,**單機支撐百萬級並發**成為常態,徹底解決「線程數上限」痛點。