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

时间:2009-04-18 15:06:45

标签: java multithreading

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

14 个答案:

答案 0 :(得分:157)

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

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

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

如果您需要比此更具体的答案,最好的选择是分析。

答案 1 :(得分:81)

嗯,很多。

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

“支持”意味着另一个问题。如果你编写一个类似

的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)

答案 2 :(得分:46)

在阅读了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

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

这很奇怪。

答案 3 :(得分:35)

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

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

我使用10,000 threads30 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

希望它有所帮助。

答案 4 :(得分:29)

绝对理论最大值通常是进程的用户地址空间除以线程堆栈大小(但实际上,如果所有内存都保留给线程堆栈,那么将没有工作计划......)。

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

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

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

答案 5 :(得分:2)

我记得听过一次Clojure谈话,他在一个专门的机器上运行他的一个应用程序,在一个拥有数千个核心(9000?)的贸易展览会上,并将它们全部加载。不幸的是,我现在找不到链接(帮助?)。

基于此,我认为可以说硬件和代码是限制因素,而不是JVM。

答案 6 :(得分:2)

在使用Charlie的DieLikeACode类之后,看起来Java线程堆栈大小是您可以创建多少线程的重要部分。

  

-Xss设置java线程堆栈大小

例如

  

java -Xss100k DieLikeADog

但是,Java有Executor接口。我会使用它,您将能够提交数千个Runnable任务,并让Executor以固定数量的线程处理这些任务。

答案 7 :(得分:1)

当我在运行 Trisquel linux (Ubuntu 18.04) 的 2GB 三星 AMD 处理器笔记本电脑上研究这个主题时。它可以管理9534个线程,然后抛出特殊异常

<块引用>
at java.base/java.lang.Thread.start0(Native Method)
at java.base/java.lang.Thread.start(Thread.java:803)
at Main.main(Main.java:11)

代码:

     public class MultithreadingRunnable implements Runnable {
         public void run(){
             System.out.println("ThreadID " +  Thread.currentThread().getId());
        }
 }



public class Main {
    public static void main(String[] ars){

    for(int i = 0;i<10000;i++){
        Thread mr = new Thread(new MultithreadingRunnable());
        mr.start();
    }
       }

    }

答案 8 :(得分:0)

答案 9 :(得分:0)

至少在Mac OS X 10.6 32bit上,操作系统有一个限制(2560)。请检查此stackoverflow thread

答案 10 :(得分:0)

最大线程数取决于以下内容:

  • 硬件配置,如微处理器,RAM。
  • 操作系统,如是32位还是64位
  • run方法中的代码。如果run方法中的代码很大,那么单个线程对象将有更多的内存需求
  • 答案 11 :(得分:0)

    现代(systemd)linux系统的附加信息。

    有许多关于这个值可能需要调整的资源(例如How to increase maximum number of JVM threads (Linux 64bit));然而,通过systemd&#34; TasksMax&#34;强加了一个新的限制。在cgroup上设置pids.max的限制。

    对于登录会话,UserTasksMax默认值是内核限制pids_max的33%(通常为12,288),可以在/etc/systemd/logind.conf中覆盖。

    对于服务,DefaultTasksMax默认值是内核限制pids_max的15%(通常为4,915)。您可以通过在&#34; systemctl edit&#34;中设置TasksMax来覆盖服务。或者更新/etc/systemd/system.conf中的DefaultTasksMax

    答案 12 :(得分:0)

    2017年...... DieLikeADog类。

    新主题#92459 线程&#34; main&#34;中的例外情况java.lang.OutOfMemoryError:无法创建新的本机线程

    i7-7700 16gb ram

    答案 13 :(得分:-4)

    您可以处理任意数量的线程;没有限制。我在观看电影和使用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();
            }
        }
    }