Wie viele Threads kann eine Java VM unterstützen?

212

Wie viele Threads kann eine Java VM unterstützen? Variiert dies je nach Anbieter? nach Betriebssystem? andere Faktoren?

McGovern-Theorie
quelle

Antworten:

170

Dies hängt von der verwendeten CPU, dem Betriebssystem, den anderen Prozessen, der von Ihnen verwendeten Java-Version und anderen Faktoren ab. Ich habe gesehen, dass ein Windows-Server> 6500 Threads hat, bevor der Computer heruntergefahren wurde. Die meisten Threads machten natürlich nichts. Sobald die Maschine ungefähr 6500 Threads (in Java) erreichte, bekam die gesamte Maschine Probleme und wurde instabil.

Meine Erfahrung zeigt, dass Java (neuere Versionen) problemlos so viele Threads verwenden kann, wie der Computer selbst problemlos hosten kann.

Natürlich muss man über genügend RAM verfügen und Java mit genügend Arbeitsspeicher gestartet haben, um alles zu tun, was die Threads tun, und um einen Stapel für jeden Thread zu haben. Jeder Computer mit einer modernen CPU (die letzten AMD- oder Intel-Generationen) und 1 bis 2 Gig Arbeitsspeicher (je nach Betriebssystem) kann problemlos eine JVM mit Tausenden von Threads unterstützen.

Wenn Sie eine genauere Antwort benötigen, ist es am besten, ein Profil zu erstellen.

Eddie
quelle
86

Ähm, viele.

Hier gibt es mehrere Parameter. Die spezifische VM sowie normalerweise gibt es auch Laufzeitparameter auf der VM. Das hängt etwas vom Betriebssystem ab: Welche Unterstützung hat das zugrunde liegende Betriebssystem für Threads und welche Einschränkungen werden ihnen auferlegt? Wenn die VM tatsächlich Threads auf Betriebssystemebene verwendet, ist das gute alte rote / grüne Thread-Ding.

Was "Unterstützung" bedeutet, ist eine andere Frage. Wenn Sie ein Java-Programm schreiben, ist das nur so etwas wie

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

(und beschweren Sie sich nicht über kleine Syntaxdetails, ich trinke meine erste Tasse Kaffee) Dann sollten Sie auf jeden Fall damit rechnen, dass Hunderte oder Tausende von Threads ausgeführt werden. Das Erstellen eines Threads ist jedoch relativ teuer, und der Overhead des Schedulers kann sehr hoch werden. Es ist unklar, ob diese Threads irgendetwas Nützliches tun könnten.

Aktualisieren

Okay, konnte nicht widerstehen. Hier ist mein kleines Testprogramm mit ein paar Verzierungen:

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();
        }
    }
}

Unter OS / X 10.5.6 unter Intel und Java 6 5 (siehe Kommentare) habe ich Folgendes erhalten

Neuer Thread # 2547
Neuer Thread # 2548
Neuer Thread # 2549
Thread kann nicht erstellt werden: 5
Neuer Thread # 2550
Ausnahme im Thread "main" java.lang.OutOfMemoryError: Neuer nativer Thread kann nicht erstellt werden
        at java.lang.Thread.start0 (native Methode)
        bei java.lang.Thread.start (Thread.java:592)
        bei DieLikeADog.main (DieLikeADog.java:6)
Charlie Martin
quelle
10
Mit wie viel Speicher haben Sie die JVM gestartet? Das zählt.
Eddie
10
Java 6 Update 13, Ubuntu 8.10 32 Bit, 4 Gigabyte RAM, Standard-JVM-Einstellungen = 6318 Threads.
Steve K
9
Heh, spiel mit der Fadenstapelgröße. Mit java -Xss100k konnte ich 19702-Threads unter Linux erstellen.
Steve K
21
Java-Xss50k brachte mir ungefähr 32k Threads. Das hat meine 4 Gigabyte RAM aber maximal gemacht. Ich musste einige laufende Prozesse stoppen, um wieder genügend Speicher auf meinem Computer zu haben, um einen neuen Prozess zum Beenden von Java zu starten;) - gute Zeiten.
Steve K
21
Mit Java 7 unter Windows 7 habe ich gerade 200.000 Threads erstellt, bevor mein System starb. Der Tasks Manager zeigte den Vorgang mit 8 GB RAM. Ich bin mir nicht sicher, warum es dort aufgehört hat ... Ich habe 12 GB RAM auf meinem Computer. Dies könnte also eine andere Grenze erreichen.
Dobes Vandermeer
50

Nachdem ich Charlie Martins Beitrag gelesen hatte, war ich neugierig, ob die Größe des Heapspeichers einen Unterschied in der Anzahl der Threads macht, die Sie erstellen können, und ich war völlig verblüfft über das Ergebnis.

Mit JDK 1.6.0_11 unter Vista Home Premium SP1 habe ich Charlies Testanwendung mit verschiedenen Heap-Größen zwischen 2 MB und 1024 MB ausgeführt.

Um beispielsweise einen 2-MB-Heap zu erstellen, würde ich die JVM mit den Argumenten -Xms2m -Xmx2m aufrufen.

Hier sind meine Ergebnisse:

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

Also, ja, die Größe des Haufens ist definitiv wichtig. Die Beziehung zwischen der Größe des Heapspeichers und der maximalen Threadanzahl ist jedoch umgekehrt proportional.

Welches ist komisch.

Benjaminismus
quelle
11
wäre sinnvoll, wenn JEDER Thread einen Heap dieser Größe erhält.
Thorbjørn Ravn Andersen
1
Vorsichtsmaßnahme: Mein Computer verfügt nicht über 2583 GB RAM. Oder tauschen. Und die JVM weist keinen threadlokalen Heapspeicher zu. Das kann es also nicht sein ...
Benjaminism
49
Die Heap-Größe reduziert den für Stapel verfügbaren Adressraum. Ein Adressraum von 256 KB / Stapel ist sinnvoll.
Tom Hawtin - Tackline
39

Ich weiß, dass diese Frage ziemlich alt ist, möchte aber nur meine Erkenntnisse teilen.

Mein Laptop kann Programme verarbeiten, die 25,000Threads erzeugen, und alle diese Threads schreiben im regelmäßigen Abstand von 2 Sekunden einige Daten in die MySQL-Datenbank.

Ich habe dieses Programm ausgeführt, 10,000 threadsdenn 30 minutes continuouslydann war auch mein System stabil und ich konnte andere normale Vorgänge ausführen, wie z. B. Surfen, Öffnen, Schließen anderer Programme usw.

Mit 25,000 threadsSystem slows downbleibt es aber reaktionsschnell.

Mit 50,000 threadsSystem stopped respondingsofort und ich musste mein System manuell neu starten.

Meine Systemdetails lauten wie folgt:

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

Vor dem Ausführen habe ich das Argument jvm gesetzt -Xmx2048m.

Ich hoffe es hilft.

Shekhar
quelle
2
"Verlangsamt" klingt wie ein Tausch.
Thorbjørn Ravn Andersen
Vielen Dank. Es war eine ziemlich solide Maschine und funktionierte fast 8 Jahre lang einwandfrei, bis sie plötzlich nicht mehr hochfuhr. Ich habe gerade Ubuntu anstelle von Windows darauf installiert und es fing wieder an, Zahlen
Shekhar
Gebratenes Core 2 Duo mit Ubuntu-Gewürzen: D
Pasupathi Rajamanickam
31

Das absolute theoretische Maximum ist im Allgemeinen der Benutzeradressraum eines Prozesses geteilt durch die Thread-Stapelgröße (obwohl in Wirklichkeit kein Arbeitsprogramm vorhanden ist, wenn Ihr gesamter Speicher für Thread-Stapel reserviert ist ...).

Unter 32-Bit-Windows beispielsweise, bei dem jeder Prozess einen Benutzeradressraum von 2 GB hat, wodurch jeder Thread eine Stapelgröße von 128 KB erhält, erwarten Sie ein absolutes Maximum von 16384 Threads (= 2 * 1024 * 1024/128). In der Praxis kann ich unter XP ungefähr 13.000 starten.

Dann denke ich, dass es Ihnen im Wesentlichen darum geht, ob (a) Sie es schaffen, so viele Threads in Ihrem Code zu jonglieren und nicht offensichtlich dumme Dinge zu tun (z. B. alle auf dasselbe Objekt warten zu lassen und dann notifyAll () aufzurufen ...). und (b) ob das Betriebssystem dies kann. Im Prinzip lautet die Antwort auf (b) "Ja", wenn die Antwort auf (a) auch "Ja" lautet.

Im Übrigen können Sie die Stapelgröße im Konstruktor des Threads angeben ; Sie müssen (und sollten wahrscheinlich nicht) mit VM-Parametern herumspielen.

Neil Coffey
quelle
1
Verwenden Sie also ein 64-Bit-Betriebssystem. Wie lange verwenden wir alle schon 64-Bit-Prozessoren?
Tom Hawtin - Tackline
Klar, ich gebe nur ein Beispiel für eine theoretische oder praktische Grenze. Wohlgemerkt, es gibt noch sehr viele 32-Bit-Maschinen (einschließlich Server) ...
Neil Coffey
2

Ich erinnere mich an einen Clojure-Vortrag, in dem er eine seiner Apps auf einem speziellen Computer auf einer Messe mit Tausenden von Kernen (9000?) Ausführen durfte, auf der alle geladen wurden. Leider kann ich den Link momentan nicht finden (Hilfe?).

Aufgrund dessen kann man mit Sicherheit sagen, dass die Hardware und Ihr Code die begrenzenden Faktoren sind, nicht die JVM.

Ken
quelle
könntest du nochmal schauen Ich würde es gerne sehen - es klingt interessant und unterstützt, dass funktionale Sprachen einfach über Kerne hinweg skalierbar sind.
Thorbjørn Ravn Andersen
Können Sie einen Link dazu bereitstellen? Ich weiß, dass Cliff Click, Jr., der leitende Ingenieur von Azul Systems, Rich Hickeys Ant Colony Simulation auf Azul's größtem JCA-System (Azul Vega 3 Series 7300 Modell 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) mit 864 Kernen und 768 ausgeführt hat GB RAM und die 700 Ameisen haben es geschafft, 700 Kerne zu maximieren. Aber 9000 Kerne, das ist ziemlich beeindruckend. Was war das für eine Maschine?
Jörg W Mittag
Ich glaube, es war die "Ants" -Simulation - hier ist ein Link, über den Rich Hickey (Clojure-Ersteller) spricht - blip.tv/clojure/clojure-concurrency-819147 . Es befand sich auf einer großen Azul-Systembox mit mehr als 800 Kernen, hauptsächlich um zu demonstrieren, wie gut Clojure im Umgang mit Multi-Core-Parallelität ist.
Mikera
@mikera lins ist abgelaufen.
Thorbjørn Ravn Andersen
2

Nach dem Herumspielen mit Charlies DieLikeACode-Klasse sieht es so aus, als ob die Größe des Java-Thread-Stacks einen großen Teil der Anzahl der Threads ausmacht, die Sie erstellen können.

-Xss Set Java Thread Stack Größe

Beispielsweise

java -Xss100k DieLikeADog

Java hat jedoch die Executor- Oberfläche. Ich würde das verwenden, Sie können Tausende von ausführbaren Aufgaben einreichen und den Executor diese Aufgaben mit einer festen Anzahl von Threads verarbeiten lassen.

Steve K.
quelle
13
Können wir es DieLikeACat nennen? Es wird weder tot noch lebendig sein, bis Sie es ausführen.
Goodwine
Vielen Dank, dass Sie auf Executors hingewiesen haben. Die Benutzer sollten es häufiger verwenden. Aber es wird nicht funktionieren, wenn das Runnable/ Callabletatsächlich kontinuierlich laufen muss, wie wenn es die Kommunikation handhaben muss. Aber es ist perfekt für SQL-Abfragen.
Matthieu
0

Zumindest unter Mac OS X 10.6 32bit gibt es eine Begrenzung (2560) durch das Betriebssystem. Überprüfen Sie diesen Stackoverflow-Thread .

Jifeng Zhang
quelle
0

Die maximale Anzahl von Threads hängt von folgenden Faktoren ab:

  • Hardwarekonfiguration wie Mikroprozessor, RAM.
  • Betriebssystem wie, ob es 32-Bit oder 64-Bit ist
  • Code innerhalb der Ausführungsmethode. Wenn der Code in der Ausführungsmethode sehr groß ist, benötigt ein einzelnes Thread-Objekt mehr Speicher
  • pgp
    quelle
    0

    Zusätzliche Informationen für moderne (systemd) Linux-Systeme.

    Es gibt viele Ressourcen zu diesen Werten, die möglicherweise angepasst werden müssen (z. B. Erhöhen der maximalen Anzahl von JVM-Threads (Linux 64-Bit) ). Es wird jedoch ein neues Limit über das systemd "TasksMax" -Limit festgelegt, das pids.max für die cgroup festlegt.

    Für Anmeldesitzungen beträgt der UserTasksMax- Standardwert 33% des Kernel-Limits pids_max (normalerweise 12.288) und kann in /etc/systemd/logind.conf überschrieben werden.

    Für Dienste beträgt der DefaultTasksMax- Standard 15% des Kernel-Limits pids_max (normalerweise 4.915). Sie können es für den Dienst überschreiben, indem Sie TasksMax in "systemctl edit" festlegen oder DefaultTasksMax in /etc/systemd/system.conf aktualisieren

    Trent Lloyd
    quelle
    0

    Jahr 2017 ... DieLikeADog Klasse.

    Neuer Thread # 92459 Ausnahme im Thread "main" java.lang.OutOfMemoryError: Neuer nativer Thread kann nicht erstellt werden

    i7-7700 16 GB RAM

    Adeptius
    quelle
    Offcourse-Antworten variieren. Ich habe 10278 mit 6 GB RAM.
    Jamie
    -4

    Sie können beliebig viele Threads verarbeiten. es gibt keine Grenzen. Ich habe den folgenden Code ausgeführt, während ich einen Film angesehen und NetBeans verwendet habe, und er hat ordnungsgemäß funktioniert / ohne den Computer anzuhalten. Ich denke, Sie können noch mehr Threads behalten als dieses Programm.

    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();
            }
        }
    }
    Anil Pal
    quelle
    7
    Ich weiß, dass dieser Kommentar sehr spät ist, aber ich glaube, der Grund, warum Sie diese vielen Threads starten und ausführen konnten, ist, dass (unter der Annahme normaler und vernünftiger Systemkonfigurationen) jeder Thread im Grunde eine Zeile aus der Ausgabe druckt und dann keinen Grund mehr dazu hat existieren und wird bald danach getötet, wodurch eine kontinuierliche Verfügbarkeit von Ressourcen sichergestellt wird.
    ucsunil
    @ucsunil Das stimmt nicht. Ich denke, Sie haben den Code falsch verstanden. Ich habe es gerade versucht und die verschiedenen Threads drucken nicht nur die erste Zeile, sondern auch ihre Namen aus. Was bedeutet, dass sie aktiv sind. Wenn Sie dachten, dass die Garbage Collection nicht referenzierte Threads recycelt, ist dies nicht der Fall, siehe hier .
    Evgeni Sergeev
    1
    Nach kurzer Zeit mainwird jedoch ein OutOfMemoryErrorauf meinen Computer geworfen , der besagt, dass keine Threads mehr erstellt werden können. Vielleicht @AnilPal, das hast du nicht bemerkt. Ich schlage vor, eine weitere print-Anweisung in die main(..)Methode aufzunehmen, um klar zu sehen, wann nach dem Auslösen des Fehlers keine neuen Threads mehr erstellt werden.
    Evgeni Sergeev
    5
    erstaunlich ... eine Entdeckung der eigentlichen Turing-Maschine ... unendliche Ressourcen.
    Josh