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


Combien de threads une machine virtuelle Java peut-elle prendre en charge? Cela varie-t-il selon le fournisseur? par système d'exploitation? d'autres facteurs?

Author: Steve Kuo, 2009-04-18

13 answers

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 de faire tomber la machine. La plupart des fils ne faisaient rien, bien sûr. Une fois que la machine a touché environ 6500 Threads (en Java), toute la machine a commencé à avoir des problèmes et à devenir instable.

Mon expérience montre que Java (versions récentes) peut heureusement consommer autant de Threads que l'ordinateur lui-même peut héberger sans problèmes.

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 avoir une pile pour chaque Thread. N'importe quelle machine avec un processeur moderne (les deux dernières générations d'AMD ou d'Intel) et avec 1 à 2 Gig de mémoire (selon le système d'exploitation) peut facilement prendre en charge une JVM avec des milliers de Threads.

Si vous avez besoin d'une réponse plus précise que celle-ci, votre meilleur pari est de profil.

 148
Author: Eddie, 2009-04-18 15:16:04

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 ainsi. Cela est quelque peu motivé par le système d'exploitation: quel support le système d'exploitation sous-jacent a-t-il pour les threads et quelles limitations leur impose-t-il? Si la machine virtuelle utilise réellement des threads au niveau du système d'exploitation, le bon vieux thread rouge/thread vert.

Ce que signifie "support" est une autre question. Si vous écrivez un programme Java c'est juste 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 à faire fonctionner des centaines ou des milliers de threads. Mais créer un thread est relativement coûteux, et la surcharge du planificateur peut devenir intense; il n'est pas clair que vous pourriez avoir ces threads faire quelque chose d'utile.

Mise à 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 les commentaires), voici ce que j'ai obtenu

New thread #2547
New thread #2548
New thread #2549
Can't create thread: 5
New thread #2550
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:592)
        at DieLikeADog.main(DieLikeADog.java:6)
 77
Author: Charlie Martin, 2009-04-18 17:05:31

Après avoir lu le post de Charlie Martin, j'étais curieux de savoir si la taille du tas faisait une différence dans le nombre de threads que vous pouvez créer, et j'étais 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 tas de 2 Mo, j'invoquerais la JVM 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 tas et le nombre maximum de threads est INVERSEMENT proportionnelle.

Ce qui est bizarre.

 44
Author: benjismith, 2009-04-18 16:18:21

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 threads 25,000 et tous ces threads écrivent des données dans la base de données MySQL à intervalle régulier de 2 secondes.

J'ai exécuté ce programme avec 10,000 threads pour 30 minutes continuously, puis aussi mon système est stable et j'ai été capable de faire d'autres opérations normales comme la navigation, l'ouverture, la fermeture d'autres programmes, etc.

Avec 25,000 threads système slows down, mais il reste sensible.

Avec 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 m'exécuter, j'ai défini l'argument jvm -Xmx2048m.

J'espère que ça aide.

 33
Author: Shekhar, 2013-04-21 08:24:39

Le maximum théorique absoluest généralement l'espace d'adressage utilisateur 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...).

Donc, 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 cherchez essentiellement à savoir si (a) vous pouvez gérer jongler avec autant de threads dans votre code et ne pas faire des choses évidemment stupides (comme les faire tous attendre sur le même objet puis appeler notifyAll()...), et (b) si le système d'exploitation peut. En principe, la réponse à (b) est "oui" si la réponse à (un) est également "oui".

Incidemment, vous pouvez spécifier la taille de la pile dans le constructeur du Thread ; vous n'avez pas besoin de (et ne devrait probablement pas) jouer avec les paramètres de la machine virtuelle pour cela.

 29
Author: Neil Coffey, 2009-04-18 20:08:53

Je me souviens avoir entendu un discours de Clojure où il devait exécuter une de ses applications sur une machine spécialisée lors d'un salon commercial avec des milliers de cœurs (9000?), et il est chargé de tous les. Malheureusement, je ne trouve pas le lien pour le moment (aide?).

Sur cette base, je pense qu'il est sûr de dire que le matériel et votre code sont les facteurs limitatifs, pas la JVM.

 2
Author: Ken, 2009-04-18 15:32:18

Après avoir joué avec la classe DieLikeACode de Charlie, il semble que la taille de la pile de threads Java soit une grande partie du nombre de threads que vous pouvez créer.

- Xss définit la taille de la pile de threads java

Par exemple

Java -Xss100k DieLikeADog

Mais, Java a la Exécuteur interface. Je l'utiliserais, vous pourrez soumettre des milliers de tâches exécutables et demander à l'exécuteur de traiter ces tâches avec un nombre fixe de threads.

 2
Author: Steve K, 2009-04-18 17:54:40

Au moins sur Mac OS X 10.6 32 bits, il y a une limite (2560) par le système d'exploitation. Cochez cette case thread stackoverflow.

 0
Author: Jifeng Zhang, 2017-05-23 12:26:25

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

  • Configuration matérielle comme microprocesseur, RAM.
  • Système d'exploitation comme s'il est 32 bits ou 64 bits
  • Code dans la méthode run. Si le code à l'intérieur de la méthode run est énorme, l'objet thread unique aura plus de mémoire requise
  •  0
    Author: pgp, 2013-05-29 04:05:53

    Informations supplémentaires pour les systèmes linux modernes (systemd).

    Il existe de nombreuses ressources à ce sujet de valeurs qui peuvent nécessiter des modifications (telles que Comment augmenter le nombre maximum de threads JVM (Linux 64bit)); cependant, une nouvelle limite est imposée par le biais de la limite systemd "TasksMax" qui définit les pid.max sur le cgroup.

    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, la valeur par défaut DefaultTasksMax 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 en mettant à jour DefaultTasksMax dans /etc/systemd/system.conf

     0
    Author: Trent Lloyd, 2017-05-23 12:03:02

    Année 2017... Classe DieLikeADog.

    Nouveau fil # 92459 Exception in thread "main" java.lang.OutOfMemoryError: impossible de créer un nouveau thread natif

    I7-7700 16 Go de ram

     0
    Author: Adeptius, 2017-10-11 20:46:13

    Vous pouvez traiter n'importe quel nombre de threads; il n'y a pas de limite. 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 garder 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();
            }
        }
    }
    
     -4
    Author: Anil Pal, 2011-11-25 04:49:28