Quanti thread può supportare una VM Java?


212

Quanti thread può supportare una VM Java? Questo varia a seconda del venditore? dal sistema operativo? altri fattori?

Risposte:


170

Questo dipende dalla CPU che stai utilizzando, dal sistema operativo, da cosa stanno facendo gli altri processi, da quale versione Java stai usando e da altri fattori. Ho visto un server Windows avere> 6500 thread prima di spegnere la macchina. La maggior parte dei thread non stava facendo nulla, ovviamente. Una volta che la macchina ha colpito circa 6500 thread (in Java), l'intera macchina ha iniziato a presentare problemi e diventare instabile.

La mia esperienza dimostra che Java (versioni recenti) può tranquillamente consumare tanti thread quanti il ​​computer stesso può ospitare senza problemi.

Ovviamente, devi avere abbastanza RAM e devi aver avviato Java con abbastanza memoria per fare tutto ciò che i thread stanno facendo e avere uno stack per ogni thread. Qualsiasi macchina con una CPU moderna (più recenti generazioni di AMD o Intel) e con 1 - 2 Gig di memoria (a seconda del sistema operativo) può facilmente supportare una JVM con migliaia di thread.

Se hai bisogno di una risposta più specifica di questa, la cosa migliore da fare è profilare.


86

Uhm, un sacco.

Ci sono diversi parametri qui. La VM specifica, inoltre, di solito ci sono anche parametri di runtime sulla VM. Questo è in qualche modo guidato dal sistema operativo: quale supporto ha il sistema operativo sottostante per i thread e quali limiti pone? Se la VM utilizza effettivamente thread a livello di sistema operativo, il buon vecchio thread rosso / thread verde.

Che cosa significa "supporto" è un'altra domanda. Se scrivi un programma Java che è semplicemente qualcosa di simile

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

(e non lamentarti dei piccoli dettagli della sintassi, sono sulla mia prima tazza di caffè), quindi dovresti sicuramente aspettarti di avere centinaia o migliaia di thread in esecuzione. Ma la creazione di un thread è relativamente costosa e il sovraccarico dello scheduler può diventare intenso; non è chiaro che potresti avere quei thread che fanno qualcosa di utile.

Aggiornare

Ok, non ho potuto resistere. Ecco il mio piccolo programma di test, con un paio di abbellimenti:

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

Su OS / X 10.5.6 su Intel e Java 6 5 (vedi commenti), ecco cosa ho ottenuto

Nuova discussione n. 2547
Nuova discussione n. 2548
Nuova discussione n. 2549
Impossibile creare il thread: 5
Nuova discussione n. 2550
Eccezione nel thread "main" java.lang.OutOfMemoryError: impossibile creare un nuovo thread nativo
        at java.lang.Thread.start0 (Metodo nativo)
        at java.lang.Thread.start (Thread.java:592)
        su DieLikeADog.main (DieLikeADog.java:6)

10
Con quanta memoria hai avviato la JVM? Quello che conta.
Eddie,

10
Java 6 update 13, Ubuntu 8.10 32 Bit, 4Gig ram, impostazioni JVM predefinite = 6318 thread.
Steve K,

9
Eh, gioca con le dimensioni della pila di thread. java -Xss100k mi ha permesso di creare thread 19702 in Linux.
Steve K,

21
java -Xss50k mi ha procurato circa 32k thread. Ciò ha portato al massimo i miei 4 grammi di montone. Ho dovuto interrompere alcuni processi in esecuzione per recuperare memoria sufficiente sulla mia macchina per eseguire il fork di un nuovo processo per uccidere java;) - bei tempi.
Steve K,

21
Utilizzando Java 7 su Windows 7 ho appena creato 200.000 thread prima che il mio sistema morisse. Task Manager ha mostrato il processo utilizzando 8 GB di RAM. Non so perché si sia fermato lì, però ... Ho 12 GB di RAM sul mio computer. Quindi questo potrebbe colpire qualche altro limite.
Dobes Vandermeer,

50

Dopo aver letto il post di Charlie Martin, ero curioso di sapere se la dimensione dell'heap fa la differenza nel numero di thread che puoi creare, e sono rimasto totalmente sbalordito dal risultato.

Utilizzando JDK 1.6.0_11 su Vista Home Premium SP1, ho eseguito l'applicazione di test di Charlie con heap di dimensioni diverse, tra 2 MB e 1024 MB.

Ad esempio, per creare un heap da 2 MB, invoco la JVM con gli argomenti -Xms2m -Xmx2m.

Ecco i miei risultati:

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

Quindi, sì, le dimensioni dell'heap sono sicuramente importanti. Ma la relazione tra dimensione heap e numero massimo di thread è INVERSAMENTE proporzionale.

Il che è strano.


11
avrebbe senso se a OGNI thread fosse assegnato un heap di quella dimensione.
Thorbjørn Ravn Andersen,

1
Avvertenza: la mia macchina non ha 2583 GB di RAM. O scambia. E la JVM non alloca spazio heap locale del thread. Quindi non può essere ...
benjismith,

49
Le dimensioni dell'heap riducono lo spazio degli indirizzi disponibile per gli stack. Lo spazio degli indirizzi di 256 KB / stack ha senso.
Tom Hawtin - tackline

1
Sì, questo mostra la stessa cosa pequenoperro.blogspot.com/2009/02/less-is-more.html
Toby,

39

So che questa domanda è piuttosto vecchia ma voglio solo condividere le mie scoperte.

Il mio laptop è in grado di gestire il programma che genera 25,000thread e tutti quei thread scrivono alcuni dati nel database MySql a intervalli regolari di 2 secondi.

Ho eseguito questo programma con 10,000 threadsper 30 minutes continuouslyallora anche il mio sistema era stabile e sono stato in grado di fare altre normali operazioni come la navigazione, l'apertura, la chiusura di altri programmi, ecc.

Con il 25,000 threadssistema, slows downma rimane reattivo.

Con il 50,000 threadssistema stopped respondingimmediatamente e ho dovuto riavviare il mio sistema manualmente.

I dettagli del mio sistema sono i seguenti:

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

Prima di eseguire ho impostato l'argomento jvm -Xmx2048m.

Spero che sia d'aiuto.


2
"Rallenta" suona come lo scambio.
Thorbjørn Ravn Andersen,

Grazie. Era una macchina piuttosto solida e ha funzionato bene per quasi 8 anni fino a quando improvvisamente ha smesso di avviarsi. Ho appena installato Ubuntu su di esso invece di Windows e ha ricominciato a scricchiolare i numeri :)
Shekhar

Duo fritto core 2 con condimento ubuntu: D
Pasupathi Rajamanickam,

31

Il massimo teorico assoluto è generalmente lo spazio di indirizzi dell'utente di un processo diviso per la dimensione dello stack del thread (anche se in realtà, se tutta la tua memoria è riservata agli stack di thread, non avrai un programma funzionante ...).

Quindi sotto Windows a 32 bit, ad esempio, dove ogni processo ha uno spazio di indirizzi utente di 2 GB, dando a ogni thread una dimensione dello stack di 128 KB, ti aspetteresti un massimo assoluto di 16384 thread (= 2 * 1024 * 1024/128). In pratica, trovo di poter avviare circa 13.000 in XP.

Poi, penso che tu sia essenzialmente nel fatto che (a) si può gestire giocoleria che molte discussioni nel codice e non fanno cose stupide, ovviamente, (come la realizzazione di tutti attesa sullo stesso oggetto quindi chiamando notifyAll () ...), e (b) se il sistema operativo può. In linea di principio, la risposta a (b) è "sì" se anche la risposta a (a) è "sì".

Per inciso, è possibile specificare la dimensione dello stack nel costruttore del thread ; per questo non è necessario (e probabilmente non dovrebbe) pasticciare con i parametri della VM.


1
Quindi usa un sistema operativo a 64 bit. Da quanto tempo usiamo tutti i processori a 64 bit?
Tom Hawtin - tackline

Certo, sto solo dando un esempio di limite teorico vs pratico. Intendiamoci, ci sono un sacco di macchine a 32 bit (compresi i server) ancora là fuori ...
Neil Coffey,

2

Ricordo di aver sentito un discorso di Clojure in cui riusciva a far funzionare una delle sue app su una macchina specializzata in una fiera con migliaia di core (9000?) E li ha caricati tutti. Purtroppo al momento non riesco a trovare il link (aiuto?).

Sulla base di ciò, penso che sia sicuro dire che l'hardware e il codice sono i fattori limitanti, non la JVM.


potresti guardare di nuovo? Mi piacerebbe vederlo: sembra interessante e sostiene che i linguaggi funzionali sono facili da scalare tra i core.
Thorbjørn Ravn Andersen,

Puoi fornire un link a quello? So che Cliff Click, Jr., l'ingegnere capo di Azul Systems ha eseguito Ant Colony Simulation di Rich Hickey sul più grande sistema JCA di Azul (Azul Vega 3 serie 7300 modello 7300 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) con 864 core e 768 GB di RAM e le 700 formiche sono riuscite a massimizzare 700 core. Ma 9000 core, è piuttosto impressionante. Che tipo di macchina era quella?
Jörg W Mittag,

Credo sia stata la simulazione di "Ants" - ecco un link in cui Rich Hickey (creatore di Clojure) ne parla - blip.tv/clojure/clojure-concurrency-819147 . Era su una grande scatola di sistemi Azul con oltre 800 core, principalmente per dimostrare quanto Clojure sia bravo a gestire la concorrenza multi-core.
Mikera,

@mikera lins è scaduto.
Thorbjørn Ravn Andersen,

2

Dopo aver giocato con la classe DieLikeACode di Charlie, sembra che la dimensione dello stack dei thread Java sia una parte enorme di quanti thread è possibile creare.

-Xss imposta la dimensione dello stack del thread Java

Per esempio

java -Xss100k DieLikeADog

Ma Java ha l' interfaccia Executor . Lo userei, sarai in grado di inviare migliaia di attività eseguibili e far eseguire a Executor tali attività con un numero fisso di thread.


13
Possiamo chiamarlo DieLikeACat? non sarà né morto né vivo finché non lo eseguirai.
Goodwine,

Grazie per aver indicato Executors, le persone dovrebbero usarlo più spesso. Ma non funzionerà se il Runnable/ Callableeffettivamente deve funzionare continuamente, come quando deve gestire la comunicazione. Ma è perfetto per le query SQL.
Matthieu,


0

Il numero massimo di thread dipende dalle seguenti cose:

  • Configurazione hardware come microprocessore, RAM.
  • Sistema operativo come se sia a 32-bit o 64-bit
  • Codice all'interno del metodo run. Se il codice all'interno del metodo run è enorme, l'oggetto a thread singolo avrà più requisiti di memoria

  • 0

    Ulteriori informazioni per i moderni sistemi linux (systemd).

    Ci sono molte risorse su questo di valori che potrebbero richiedere delle modifiche (come Come aumentare il numero massimo di thread JVM (Linux 64 bit) ); tuttavia viene imposto un nuovo limite tramite il limite "TasksMax" del sistema che imposta pids.max sul cgroup.

    Per le sessioni di accesso, il valore predefinito di UserTasksMax è il 33% del limite del kernel pids_max (in genere 12.288) e può essere sostituito in /etc/systemd/logind.conf.

    Per i servizi, DefaultTasksMax è il 15% del limite del kernel pids_max (di solito 4.915). Puoi sovrascriverlo per il servizio impostando TasksMax in "systemctl edit" o aggiornando DefaultTasksMax in /etc/systemd/system.conf


    0

    Anno 2017 ... Classe DieLikeADog.

    New thread # 92459 Eccezione nel thread "main" java.lang.OutOfMemoryError: impossibile creare un nuovo thread nativo

    i7-7700 16 gb di ram


    Le risposte fuori sede possono variare. Ho ottenuto 10278 con 6 GB di RAM.
    Jamie,

    -4

    È possibile elaborare un numero qualsiasi di thread; non c'è limite. Ho eseguito il codice seguente durante la visione di un film e l'utilizzo di NetBeans, e ha funzionato correttamente / senza arrestare la macchina. Penso che puoi tenere ancora più thread di quanti ne faccia questo programma.

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

    7
    So che questo commento è molto tardi, ma credo che il motivo per cui sei stato in grado di avviare ed eseguire questi molti thread sia perché (supponendo configurazioni di sistema normali e ragionevoli) ogni thread in pratica stampa una riga dall'output e quindi non ha più motivo di esiste e viene ucciso poco dopo, garantendo così una disponibilità continua di risorse.
    ucsunil,

    @ucsunil Non è vero. Penso che tu abbia letto male il codice. L'ho appena provato e i vari thread non stampano solo la prima riga, ma anche i loro nomi. Ciò significa che sono attivi. Se pensavi che la garbage collection riciclasse i thread senza riferimento, non lo fa, vedi qui .
    Evgeni Sergeev,

    1
    Tuttavia, dopo poco tempo, mainlancerò un messaggio OutOfMemoryErrorsul mio computer, dicendo che non è possibile creare altri thread. Forse @AnilPal, non te ne sei accorto. Suggerisco di includere un'altra istruzione di stampa nel main(..)metodo, per vedere chiaramente quando smette di creare nuovi thread dopo aver lanciato l'errore.
    Evgeni Sergeev,

    5
    incredibile ... una scoperta dell'attuale macchina di Turing ... risorse infinite.
    Josh,
    Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
    Licensed under cc by-sa 3.0 with attribution required.