当前位置:  开发笔记 > 编程语言 > 正文

Java VM可以支持多少个线程?

如何解决《JavaVM可以支持多少个线程?》经验,为你挑选了5个好方法。

Java VM可以支持多少个线程?这是否因供应商而异?通过操作系统?其他因素?



1> Eddie..:

这取决于您正在使用的CPU,操作系统,其他进程正在执行的CPU,您正在使用的Java版本以及其他因素.我看到Windows服务器在关机之前有> 6500个线程.当然,大多数线程都没有做任何事情.一旦机器击中大约6500个线程(在Java中),整个机器开始出现问题并变得不稳定.

我的经验表明,Java(最新版本)可以愉快地使用尽可能多的线程,因为计算机本身可以毫无问题地托管.

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

如果您需要比这更具体的答案,最好的办法是分析.



2> Charlie Mart..:

嗯,很多.

这里有几个参数.特定的VM,以及VM上通常还有运行时参数.这在某种程度上是由操作系统驱动的:底层操作系统对线程有什么支持,它对它们有什么限制?如果VM实际上使用OS级别的线程,那么旧的红色线程/绿色线程就好了.

"支持"意味着另一个问题.如果你编写一个类似的Java程序

   class DieLikeADog {
         public static void main(String[] argv){
             for(;;){
                new Thread(new SomeRunaable).start();
             }
         }
    }

(并且不要抱怨很少的语法细节,我正在喝第一杯咖啡)然后你当然应该会有数百或数千个线程在运行.但是创建一个线程相对昂贵,并且调度程序开销会变得很大; 目前还不清楚你是否可以让这些线程做任何有用的事情.

更新

好吧,无法抗拒.这是我的小测试程序,有几个装饰:

public class DieLikeADog {
    private static Object s = new Object();
    private static int count = 0;
    public static void main(String[] argv){
        for(;;){
            new Thread(new Runnable(){
                    public void run(){
                        synchronized(s){
                            count += 1;
                            System.err.println("New thread #"+count);
                        }
                        for(;;){
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e){
                                System.err.println(e);
                            }
                        }
                    }
                }).start();
        }
    }
}

在Intel上的OS/X 10.5.6和Java 6 5上(参见注释),这就是我所得到的

New thread #2547
New thread #2548
New thread #2549
Can't create thread: 5
New thread #2550
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:592)
        at DieLikeADog.main(DieLikeADog.java:6)


java -Xss50k给了我大约32k个线程.尽管如此,我的4g公羊也是最大的.我不得不停止一些正在运行的进程,以便在我的机器上获得足够的内存来分叉一个新进程来杀死java;) - 好时光.
在Windows 7上使用Java 7我刚刚在系统死机之前创建了200,000个线程.任务管理器使用8GB RAM显示该过程.不知道为什么它停在那里,但是......我的计算机上有12GB的RAM.所以这可能会达到一些其他限制.
你用JVM启动了多少内存?那很重要.
Java 6更新13,Ubuntu 8.10 32位,4Gig ram,默认JVM设置= 6318线程.
嘿,玩线程堆栈大小.java -Xss100k允许我在Linux中创建19702个线程.
这个程序有一个缺陷:可能已经启动了更多的线程,无法进入打印线程ID的行.然后会发生OOM异常,并且您将拥有一个不确定地低于实际线程数的数字.
可以在[这里]找到一个处理它的程序(http://stackoverflow.com/a/10676165/1103872).好吧,我写了它,但它不是广告,它都是以客观科学的名义:)
好吧,你诱惑我,@ Eddie,但是用-Xmx和-Xss搞乱只会导致许多组合效果不佳.我需要一个想要研究项目的本科生.
WinXP(32位),C2Q6600,4GB RAM,jdk1.6.0_11(32位)和默认的JVM选项让我获得#5587线程.奇怪的是,有了更多的JVM内存,我可以创建更少的线程:只使用"-Xms1G -Xmx1G"JVM选项#2644.
但是,我可以有多个这样的JVM与5000个线程(请参阅Windows任务管理器性能|合计|主题),所以显然OS限制高得多.

3> benjismith..:

在阅读了Charlie Martin的帖子之后,我很好奇堆大小是否会对你可以创建的线程数产生任何影响,而且我对结果完全傻了.

在Vista Home Premium SP1上使用JDK 1.6.0_11,我执行了具有不同堆大小的Charlie测试应用程序,介于2 MB和1024 MB之间.

例如,要创建一个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

所以,是的,堆大小绝对重要.但堆大小和最大线程数之间的关系是反比例的.

这很奇怪.


堆大小减少了可用于堆栈的地址空间.256K /堆栈的地址空间是有意义的.
如果EACH线程被赋予该大小的堆,那将是有意义的.

4> Shekhar..:

我知道这个问题很老,但只想分享我的发现.

我的笔记本电脑能够处理产生25,000线程的程序,并且所有这些线程以2秒的固定间隔在MySql数据库中写入一些数据.

我跑这个程序与10,000 threads用于30 minutes continuously随后还我的系统是稳定的,我是能够做到像浏览,开放等正常操作,关闭其他程序,等等.

使用25,000 threads系统slows down但仍保持响应.

随着50,000 threads系统stopped responding瞬间,我不得不手动重新启动我的系统.

我的系统详情如下:

Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6

在运行之前我设置了jvm参数-Xmx2048m.

希望能帮助到你.



5> Neil Coffey..:

绝对理论上的最大值通常是一个进程的用户地址空间由线程堆栈大小分(虽然在现实中,如果你所有的记忆被保留用于线程堆栈,你会不会有一个工作程序......).

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

然后,我认为你是否(a)可以管理代码中的许多线程并且不做明显愚蠢的事情(例如让它们等待同一个对象然后调用notifyAll()...), (b)操作系统是否可以.原则上,如果(a)的答案也是"是",则(b)的答案为"是".

顺便提一下,您可以在Thread的构造函数中指定堆栈大小 ; 你不需要(也可能不应该)搞乱VM参数.

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有