Combien de threads une machine virtuelle Java peut-elle prendre en charge?


212

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:


170

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.


86

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.

Mettre à jour

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)

10
Avec combien de mémoire avez-vous démarré la JVM? C'est important.
Eddie

10
Java 6 mise à jour 13, Ubuntu 8.10 32 bits, RAM 4Gig, paramètres JVM par défaut = 6318 threads.
Steve K

9
Hé, jouez avec la taille de la pile de fils. java -Xss100k m'a permis de créer des threads 19702 sous Linux.
Steve K

21
java -Xss50k m'a fait environ 32k threads. Mais ça a fait sortir mes 4 Go de RAM. J'ai dû arrêter certains processus en cours d'exécution pour récupérer suffisamment de mémoire sur ma machine pour lancer un nouveau processus pour tuer Java;) - de bons moments.
Steve K

21
En utilisant Java 7 sur Windows 7, je viens de créer 200 000 threads avant la mort de mon système. Le gestionnaire de tâches a montré le processus en utilisant 8 Go de RAM. Je ne sais pas pourquoi cela s'est arrêté là, cependant ... J'ai 12 Go de RAM sur mon ordinateur. Donc, cela peut atteindre une autre limite.
Dobes Vandermeer

50

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.


11
aurait du sens si CHAQUE thread reçoit un tas de cette taille.
Thorbjørn Ravn Andersen

1
Attention: ma machine n'a pas 2583 Go de RAM. Ou échangez. Et la JVM n'alloue pas d'espace de tas local au thread. Donc ça ne peut pas être ça ...
benjismith

49
La taille du segment réduit l'espace d'adressage disponible pour les piles. L'espace d'adressage de 256 Ko / pile est logique.
Tom Hawtin - tackline

1
Oui, cela montre la même chose pequenoperro.blogspot.com/2009/02/less-is-more.html
Toby

39

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,000threads 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 threadspour 30 minutes continuouslyalors 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 threadssystème slows downmais il reste réactif.

Avec le 50,000 threadssystème stopped respondinginstantané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.


2
"Ralentit" sonne comme un échange.
Thorbjørn Ravn Andersen

Merci. C'était une machine assez solide et a bien fonctionné pendant près de 8 ans jusqu'à ce que soudainement, elle cesse de démarrer. Je viens d'installer Ubuntu dessus au lieu de Windows et il a recommencé à croquer les chiffres :)
Shekhar

Duo Fried Core 2 avec assaisonnement Ubuntu: D
Pasupathi Rajamanickam

31

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.


1
Utilisez donc un système d'exploitation 64 bits. Depuis combien de temps utilisons-nous tous des processeurs 64 bits?
Tom Hawtin - tackline

Bien sûr, je donne juste un exemple de limite théorique vs pratique. Attention, il y a énormément de machines 32 bits (y compris des serveurs) encore là-bas ...
Neil Coffey

2

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.


pourriez-vous regarder à nouveau? Je voudrais le voir - cela semble intéressant et soutient que les langages fonctionnels sont faciles à mettre à l'échelle sur les cœurs.
Thorbjørn Ravn Andersen

Pouvez-vous fournir un lien vers cela? Je sais que Cliff Click, Jr., l'ingénieur principal d'Azul Systems a exécuté la simulation de colonie de fourmis de Rich Hickey sur le plus grand système JCA d'Azul (Azul Vega 3 Series 7300 Model 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) avec 864 cœurs et 768 Go de RAM et les 700 fourmis ont réussi à maximiser 700 cœurs. Mais 9000 cœurs, c'est assez impressionnant. Quel genre de machine était-ce?
Jörg W Mittag

C'était la simulation "Fourmis" je crois - voici un lien où Rich Hickey (créateur de Clojure) en parle - blip.tv/clojure/clojure-concurrency-819147 . C'était sur une grande boîte de systèmes Azul avec plus de 800 cœurs, principalement pour démontrer à quel point Clojure est capable de gérer la concurrence multicœur.
mikera

@mikera lins a expiré.
Thorbjørn Ravn Andersen

2

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.


13
Pouvons-nous l'appeler DieLikeACat? il ne sera ni mort ni vivant tant que vous ne l'exécuterez pas.
Goodwine

Merci de pointer vers Executors, les gens devraient l'utiliser plus souvent. Mais cela ne fonctionnera pas si le Runnable/ Callabledoit réellement s'exécuter en continu, comme lorsqu'il doit gérer la communication. Mais c'est parfait pour les requêtes SQL.
Matthieu


0

Le nombre maximum de threads dépend des éléments suivants:

  • Configuration matérielle comme microprocesseur, RAM.
  • Système d'exploitation comme s'il était 32 bits ou 64 bits
  • Code à l'intérieur de la méthode run. Si le code à l'intérieur de la méthode d'exécution est énorme, alors l'objet à thread unique aura plus de mémoire

  • 0

    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


    0

    Année 2017 ... classe DieLikeADog.

    Nouveau thread # 92459 Exception dans le thread "principal" java.lang.OutOfMemoryError: impossible de créer un nouveau thread natif

    i7-7700 16gb ram


    Les réponses hors cours varieront. J'ai eu 10278 avec 6 Go de RAM.
    jamie

    -4

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

    7
    Je sais que ce commentaire est très tardif, mais je pense que la raison pour laquelle vous avez pu démarrer et exécuter ces nombreux threads est que (en supposant des configurations système normales et raisonnables), chaque thread imprime essentiellement une ligne de sortie et n'a plus de raison de existent et sont tués peu de temps après, assurant ainsi une disponibilité continue des ressources.
    ucsunil

    @ucsunil Ce n'est pas vrai. Je pense que vous avez mal lu le code. Je viens de l'essayer et les différents threads impriment non seulement la première ligne, mais aussi leurs noms. Ce qui signifie qu'ils sont actifs. Si vous pensiez que la récupération de place recyclera les threads non référencés, ce n'est pas le cas, voir ici .
    Evgeni Sergeev

    1
    Cependant, après un court instant, mainjettera un OutOfMemoryErrorsur 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.
    Evgeni Sergeev

    5
    incroyable ... une découverte de la machine Turing actuelle ... des ressources infinies.
    Josh
    En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
    Licensed under cc by-sa 3.0 with attribution required.