Combien de threads une machine virtuelle Java peut-elle prendre en charge? Cela varie-t-il selon le fournisseur? par système d'exploitation? autres facteurs?
Combien de threads une machine virtuelle Java peut-elle prendre en charge? Cela varie-t-il selon le fournisseur? par système d'exploitation? autres facteurs?
Réponses:
Cela dépend du processeur que vous utilisez, du système d'exploitation, de ce que font les autres processus, de la version Java que vous utilisez et d'autres facteurs. J'ai vu un serveur Windows avoir> 6500 threads avant d'arrêter la machine. La plupart des fils ne faisaient rien, bien sûr. Une fois que la machine a atteint environ 6500 threads (en Java), la machine entière a commencé à avoir des problèmes et à devenir instable.
Mon expérience montre que Java (versions récentes) peut consommer avec plaisir autant de threads que l'ordinateur lui-même peut héberger sans problème.
Bien sûr, vous devez avoir suffisamment de RAM et vous devez avoir démarré Java avec suffisamment de mémoire pour faire tout ce que les Threads font et pour avoir une pile pour chaque Thread. Toute machine dotée d'un processeur moderne (les dernières générations d'AMD ou Intel) et de 1 à 2 Go de mémoire (selon le système d'exploitation) peut facilement prendre en charge une machine virtuelle Java avec des milliers de threads.
Si vous avez besoin d'une réponse plus précise que celle-ci, votre meilleur pari est de profiler.
Euh, beaucoup.
Il y a plusieurs paramètres ici. La machine virtuelle spécifique, plus il y a généralement des paramètres d'exécution sur la machine virtuelle également. Cela est quelque peu dicté par le système d'exploitation: quelle prise en charge le système d'exploitation sous-jacent a-t-il pour les threads et quelles limitations y met-il? Si la machine virtuelle utilise réellement des threads au niveau du système d'exploitation, la bonne vieille chose de thread rouge / thread vert.
Ce que signifie «soutien» est une autre question. Si vous écrivez un programme Java qui ressemble à quelque chose comme
class DieLikeADog {
public static void main(String[] argv){
for(;;){
new Thread(new SomeRunaable).start();
}
}
}
(et ne vous plaignez pas des petits détails de syntaxe, je suis sur ma première tasse de café), alors vous devriez certainement vous attendre à ce que des centaines ou des milliers de threads s'exécutent. Mais la création d' un thread est relativement coûteuse et les frais généraux du planificateur peuvent devenir intenses; il n'est pas clair que ces discussions pourraient faire quelque chose d'utile.
D'accord, je n'ai pas pu résister. Voici mon petit programme de test, avec quelques embellissements:
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();
}
}
}
Sur OS / X 10.5.6 sur Intel et Java 6 5 (voir commentaires), voici ce que j'ai
Nouveau thread # 2547 Nouveau thread # 2548 Nouveau thread # 2549 Impossible de créer un fil: 5 Nouveau thread # 2550 Exception dans le thread "principal" java.lang.OutOfMemoryError: impossible de créer un nouveau thread natif à java.lang.Thread.start0 (méthode native) à java.lang.Thread.start (Thread.java:592) sur DieLikeADog.main (DieLikeADog.java:6)
Après avoir lu le post de Charlie Martin, j'étais curieux de savoir si la taille du tas fait une différence dans le nombre de threads que vous pouvez créer, et j'ai été totalement abasourdi par le résultat.
En utilisant JDK 1.6.0_11 sur Vista Home Premium SP1, j'ai exécuté l'application de test de Charlie avec différentes tailles de tas, entre 2 Mo et 1024 Mo.
Par exemple, pour créer un segment de mémoire de 2 Mo, j'appelle la machine virtuelle Java avec les arguments -Xms2m -Xmx2m.
Voici mes résultats:
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
Donc, oui, la taille du tas compte vraiment. Mais la relation entre la taille du segment de mémoire et le nombre maximal de threads est INVERSEMENT proportionnelle.
C'est bizarre.
Je sais que cette question est assez ancienne, mais je veux juste partager mes conclusions.
Mon ordinateur portable est capable de gérer un programme qui génère des 25,000
threads et tous ces threads écrivent des données dans la base de données MySql à un intervalle régulier de 2 secondes.
J'ai couru ce programme avec 10,000 threads
pour 30 minutes continuously
alors aussi mon système était stable et j'ai pu faire d' autres opérations normales telles que la navigation, l' ouverture, la fermeture d' autres programmes, etc.
Avec 25,000 threads
système slows down
mais il reste réactif.
Avec le 50,000 threads
système stopped responding
instantanément et j'ai dû redémarrer mon système manuellement.
Les détails de mon système sont les suivants:
Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6
Avant de lancer, je mets l'argument jvm -Xmx2048m
.
J'espère que ça aide.
Le maximum théorique absolu est généralement l' espace d'adressage d' un processus divisé par la taille de la pile de threads (bien qu'en réalité, si toute votre mémoire est réservée aux piles de threads, vous n'aurez pas de programme de travail ...).
Ainsi, sous Windows 32 bits, par exemple, où chaque processus a un espace d'adressage utilisateur de 2 Go, donnant à chaque thread une taille de pile de 128 Ko, vous vous attendez à un maximum absolu de 16384 threads (= 2 * 1024 * 1024/128). En pratique, je trouve que je peux démarrer environ 13 000 sous XP.
Ensuite, je pense que vous êtes essentiellement dans la question de savoir si (a) vous pouvez gérer le jonglage de nombreux threads dans votre code et ne pas faire des choses évidemment stupides (comme les faire tous attendre sur le même objet puis appeler notifierAll () ...), et (b) si le système d'exploitation le peut. En principe, la réponse à (b) est "oui" si la réponse à (a) est également "oui".
Soit dit en passant, vous pouvez spécifier la taille de la pile dans le constructeur du thread ; vous n'avez pas besoin (et probablement ne devriez pas) de jouer avec les paramètres de la VM pour cela.
Je me souviens avoir entendu un discours de Clojure où il a pu exécuter l'une de ses applications sur une machine spécialisée lors d'un salon avec des milliers de cœurs (9000?), Et il les a tous chargés. Malheureusement, je ne trouve pas le lien pour le moment (aide?).
Sur cette base, je pense qu'il est prudent de dire que le matériel et votre code sont les facteurs limitants, pas la JVM.
Après avoir joué avec la classe DieLikeACode de Charlie, il semble que la taille de la pile de threads Java représente une grande partie du nombre de threads que vous pouvez créer.
-Xss définir la taille de la pile de threads java
Par exemple
java -Xss100k DieLikeADog
Mais, Java a l' interface Executor . J'utiliserais cela, vous pourrez soumettre des milliers de tâches Runnable et demander à l'Executor de traiter ces tâches avec un nombre fixe de threads.
Runnable
/ Callable
doit réellement s'exécuter en continu, comme lorsqu'il doit gérer la communication. Mais c'est parfait pour les requêtes SQL.
Au moins sur Mac OS X 10.6 32 bits, il y a une limite (2560) par le système d'exploitation. Vérifiez ce thread stackoverflow .
Le nombre maximum de threads dépend des éléments suivants:
Informations supplémentaires pour les systèmes Linux modernes (systemd).
Il existe de nombreuses ressources à ce sujet de valeurs qui peuvent avoir besoin d'être modifiées (telles que Comment augmenter le nombre maximal de threads JVM (Linux 64 bits) ); cependant, une nouvelle limite est imposée au moyen de la limite systemd "TasksMax" qui définit pids.max sur le groupe de contrôle.
Pour les sessions de connexion, la valeur par défaut UserTasksMax est de 33% de la limite du noyau pids_max (généralement 12 288) et peut être remplacée dans /etc/systemd/logind.conf.
Pour les services, DefaultTasksMax par défaut est de 15% de la limite du noyau pids_max (généralement 4 915). Vous pouvez le remplacer pour le service en définissant TasksMax dans "systemctl edit" ou mettre à jour DefaultTasksMax dans /etc/systemd/system.conf
Vous pouvez traiter n'importe quel nombre de threads; il n'y a pas de limites. J'ai exécuté le code suivant en regardant un film et en utilisant NetBeans, et cela a fonctionné correctement / sans arrêter la machine. Je pense que vous pouvez conserver encore plus de threads que ce programme.
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
jettera un OutOfMemoryError
sur ma machine, disant qu'il ne peut plus créer de threads. Peut-être que @AnilPal, vous ne l'avez pas remarqué. Je suggère d'inclure une autre instruction d'impression dans la main(..)
méthode, pour voir clairement quand elle cesse de créer de nouveaux threads après avoir lancé l'erreur.