Java虚拟机线程支持上限:CPU、操作系统、内存及其他关键因素解析
McGovernTheory 在 StackOverflow 上提出了这个问题:

Java虚拟机支持多少个线程?和虚拟机开发者有关系吗?那么操作系统呢?还有其他因素吗?
艾迪的回答:
这取决于您使用的 CPU、操作系统、其他进程正在执行的操作、您使用的 Java 版本以及其他因素。我曾经看到一台 Windows 服务器在宕机之前有超过 6500 个线程。当然,大多数线程什么都不做。一旦机器上有近 6500 个线程(在 Java 中),机器就会开始出现问题并变得不稳定。
根据我的经验,JVM容纳的线程数量与计算机本身的性能呈正相关。
当然,你必须有足够的本机内存,并为Java分配足够的内存,这样每个线程都可以有一个堆栈(虚拟机堆栈),可以做任何它想做的事情。任何具有现代 CPU(AMD 或最近的 Intel 几代)和 1-2G 内存(取决于操作系统)的机器都可以轻松支持具有数千个线程的 Java 虚拟机。
如果您需要更准确的答案,最好自己进行压力测试。
查理·马丁的回答:
这里有很多参数(可以设置)。对于特定的虚拟机,它将有自己的运行时参数。 (最大线程数)一定程度上是由操作系统决定的:操作系统底层对线程提供了哪些支持?有什么限制?虚拟机使用本机操作系统线程、红色线程还是绿色线程?
操作系统提供的支持是另一个问题。如果你写一个像这样的Java程序:
复制代码代码如下:
类 DieLikeADog {
公共静态无效主(字符串[] argv){
为了(;;){
new Thread(new SomeRunaable).start();
(不要抱怨语法细节,这只是开始。)然后你当然希望获得数百或数千个正在运行的线程。但创建线程的成本比较大,(多线程)调度的开销就会变得突出。这些线程是否可以做有用的事情还不确定。
升级版
好吧,已经等不及了!下面是我添加了一些修饰的一个小测试程序:
复制代码代码如下:
公共类 DieLikeADog {
私有静态对象 s = new Object();
私有静态 int 计数 = 0;
公共静态无效主(字符串[] argv){
为了(;;){
新线程(新可运行(){
公共无效运行(){
同步{
计数 += 1;
System.err.println("新线程#"+count);
为了(;;){
尝试 {
线程睡眠(1000);
} catch (异常 e){
System.err.println(e);
})。开始();
在Intel的OS/X 10.5.6系统上,Java 5的输出如下:
复制代码代码如下:
新线程#2547
新线程#2548
新线程#2549
无法创建线程:5
新线程#2550
线程“main”中的异常 java.lang.OutOfMemoryError:无法创建新的本机线程
在java.lang.Thread.start0(本机方法)
在 java.lang.Thread.start(Thread.java:592)
在 DieLikeADog.main(DieLikeADog.java:6)
本吉史密斯的回答:
阅读 Charlie Martin 的回复后,我很好奇堆大小是否会影响创建的线程数量,结果令我震惊:在 Vista Home Premium SP1 系统上,使用 JDK 1.6.0_11,设置堆内存大小从2M到1024M来执行Charlie的测试程序。例如:创建2M堆内存,我使用的虚拟机参数是:-Xms2m -Xmx2m。
这是我的测试结果:
复制代码代码如下:
2mb --> 5744 线程
4mb --> 5743 线程
8mb --> 5735 个线程
12MB --> 5724 线程
16mb --> 5712 线程
24mb --> 5687 线程
32MB --> 5662 线程
48mb --> 5610 线程
64mb --> 5561 个线程
96mb --> 5457 个线程
128mb --> 5357 个线程
192MB --> 5190 线程
256MB --> 5014 个线程
384mb --> 4606 线程
512MB --> 4202 线程
768mb --> 3388 个线程
1024mb --> 2583 线程
因此,堆大小确实很重要。但是,堆大小和最大线程数之间存在反比关系。
这太奇怪了!
尼尔·科菲的回答:
绝对理论最大线程数是进程的用户地址空间除以线程堆栈的大小(实际上,如果所有内存都被线程堆栈使用,将没有程序可以运行)。因此,以32位Windows系统为例,每个进程的用户地址空间为2G。如果每个线程堆栈的大小为128K,则最多有16384(=2*1024*1024 / 128)个线程。实际上在XP系统上,我发现大约可以启动13000个线程。
然后,我认为,您的问题本质上是:(a)您能否有效地管理代码中的许多线程,而不让它们做明显愚蠢的事情(例如让它们在同一个对象上运行) On wait 随后被称为notifyAll()... )、(b)操作系统能否有效管理这么多线程。基本上,如果(a)的答案是“是”,那么(b)的答案也是“是”。
巧合的是,您可以在 Thread 构造函数中设置线程堆栈大小,但您不需要也不应该将其与虚拟机参数混淆。