Java虚拟机线程支持上限:CPU、操作系统、内存及其他关键因素解析

McGovernTheory 在 StackOverflow 上提出了这个问题:

Java虚拟机线程支持上限:CPU、操作系统、内存及其他关键因素解析

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 构造函数中设置线程堆栈大小,但您不需要也不应该将其与虚拟机参数混淆。

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

26阅读

java中冒号,java双冒号

2026年09月06日

23阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

27阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

23阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

24阅读