一个Java虚拟机可以支持多少线程?这因供应商而异吗?按操作系统?其他因素?


当前回答

至少在Mac OS X 10.6 32位上,操作系统有一个限制(2560)。检查这个stackoverflow线程。

其他回答

在阅读了Charlie Martin的文章后,我很好奇堆大小是否会对您可以创建的线程数量产生影响,结果完全让我目瞪口呆。

使用Vista Home Premium SP1上的JDK 1.6.0_11,我执行Charlie的测试应用程序,使用不同的堆大小,在2mb到1024mb之间。

例如,要创建一个2 MB的堆,我将使用参数-Xms2m -Xmx2m调用JVM。

以下是我的结果:

2 mb --> 5744 threads
4 mb --> 5743 threads
8 mb --> 5735 threads
12 mb --> 5724 threads
16 mb --> 5712 threads
24 mb --> 5687 threads
32 mb --> 5662 threads
48 mb --> 5610 threads
64 mb --> 5561 threads
96 mb --> 5457 threads
128 mb --> 5357 threads
192 mb --> 5190 threads
256 mb --> 5014 threads
384 mb --> 4606 threads
512 mb --> 4202 threads
768 mb --> 3388 threads
1024 mb --> 2583 threads

堆大小肯定很重要。但是堆大小和最大线程数之间的关系是反比的。

这很奇怪。

至少在Mac OS X 10.6 32位上,操作系统有一个限制(2560)。检查这个stackoverflow线程。

理论上的绝对最大值通常是进程的用户地址空间除以线程堆栈大小(尽管在现实中,如果所有的内存都留给线程堆栈,那么程序就无法正常工作……)

例如,在32位Windows下,每个进程的用户地址空间为2GB,给每个线程128K的堆栈大小,您期望的绝对最大值为16384个线程(=2*1024*1024 / 128)。在实践中,我发现在XP下我可以启动大约13,000。

然后,我认为你本质上是(a)你是否可以在你的代码中管理这么多线程,而不是做明显的愚蠢的事情(比如让它们都等待同一个对象,然后调用notifyAll()…),以及(b)操作系统是否可以。原则上,如果(a)的答案也是“是”,那么(b)的答案就是“是”。

顺便说一句,你可以在Thread的构造函数中指定堆栈大小;你不需要(可能也不应该)为此而打乱VM参数。

这取决于您使用的CPU、操作系统、其他进程在做什么、您使用的Java发行版以及其他因素。我曾经见过一台Windows服务器在关闭机器之前有> 6500个线程。当然,大多数线程都没有做任何事情。一旦机器达到大约6500个线程(在Java中),整个机器就开始出现问题,变得不稳定。

我的经验表明,Java(最新版本)可以愉快地使用计算机本身所能承载的尽可能多的线程,而不会出现问题。

当然,你必须有足够的RAM,你必须有足够的内存来启动Java,以完成线程正在做的所有事情,并为每个线程有一个堆栈。任何具有现代CPU(最近几代AMD或Intel)和1 - 2gig内存(取决于操作系统)的机器都可以轻松支持具有数千个线程的JVM。

如果你需要一个比这更具体的答案,你最好的选择是侧写。

你可以处理任意数量的线程;没有限制。我在看电影和使用NetBeans时运行了下面的代码,它正常工作/没有停止机器。我认为你可以保留比这个程序更多的线程。

class A extends Thread {
    public void run() {
        System.out.println("**************started***************");
        for(double i = 0.0; i < 500000000000000000.0; i++) {
            System.gc();
            System.out.println(Thread.currentThread().getName());
        }
        System.out.println("************************finished********************************");
    }
}

public class Manager {
    public static void main(String[] args) {
        for(double j = 0.0; j < 50000000000.0; j++) {
            A a = new A();
            a.start();
        }
    }
}