Quanti thread può supportare una VM Java? Questo varia a seconda del venditore? dal sistema operativo? altri fattori?
Quanti thread può supportare una VM Java? Questo varia a seconda del venditore? dal sistema operativo? altri fattori?
Risposte:
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.
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.
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)
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.
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,000
thread e tutti quei thread scrivono alcuni dati nel database MySql a intervalli regolari di 2 secondi.
Ho eseguito questo programma con 10,000 threads
per 30 minutes continuously
allora 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 threads
sistema, slows down
ma rimane reattivo.
Con il 50,000 threads
sistema stopped responding
immediatamente 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.
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.
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.
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.
Runnable
/ Callable
effettivamente deve funzionare continuamente, come quando deve gestire la comunicazione. Ma è perfetto per le query SQL.
Almeno su Mac OS X 10.6 a 32 bit, esiste un limite (2560) per il sistema operativo. Controlla questo thread stackoverflow .
Il numero massimo di thread dipende dalle seguenti cose:
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
È 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();
}
}
}
main
lancerò un messaggio OutOfMemoryError
sul 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.