web-dev-qa-db-fra.com

Combien de threads un Java VM peut-il prendre en charge?

Combien de threads un Java VM peut-il prendre en charge? Cela varie-t-il selon le vendeur? par système d'exploitation? autres facteurs?

199
McGovernTheory

Cela dépend du processeur que vous utilisez, du système d'exploitation, des autres processus en cours, de la version que vous utilisez Java et d'autres facteurs. J'ai vu un serveur Windows compter plus de 6500 threads avant de mettre la machine hors tension. La plupart des discussions 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 facilement consommer autant de threads que l'ordinateur lui-même peut héberger sans problèmes.

Bien sûr, vous devez avoir assez de RAM et vous devez avoir démarré Java avec assez de mémoire pour faire tout ce que font les threads et disposer d'une pile pour chaque thread. Toute machine dotée d’un processeur moderne (dernières générations d’AMD ou d’Intel) et disposant de 1 à 2 Go de mémoire (en fonction du système d’exploitation) peut facilement prendre en charge une machine virtuelle avec milliers de threads.

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

159
Eddie

Euh, beaucoup.

Il y a plusieurs paramètres ici. La VM spécifique, plus il y a généralement des paramètres d'exécution sur la VM. Cela dépend en partie du système d'exploitation: quel support l'OS sous-jacent a-t-il pour les threads et quelles limitations le met-il? Si la VM utilise en réalité des threads au niveau du système d'exploitation, c'est le bon vieux fil rouge/vert.

Ce que "support" signifie 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 la syntaxe, je suis sur ma première tasse de café) alors vous devriez certainement vous attendre à avoir des centaines, voire des milliers de fils en cours d'exécution. Mais créer un thread est relativement coûteux et les frais généraux du planificateur peuvent devenir intenses; il n'est pas clair que ces threads puissent faire quelque chose d'utile.

Mise à jour

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

Sous OS/X 10.5.6 sur Intel et Java 6 5 (voir les commentaires), voici ce que j'ai

 Nouvelle discussion # 2547 
 Nouvelle discussion # 2548 
 Nouvelle discussion # 2549 
 Impossible de créer une discussion: 5 
 Nouvelle discussion # 2550 
 Exception dans le fil "principal" Java.lang.OutOfMemoryError: impossible de créer un nouveau fil natif 
 Sur Java.lang.Thread.start0 (Méthode native) 
 Sur Java.lang.Thread. commencer (Thread.Java:592) 
 à DieLikeADog.main (DieLikeADog.Java:6) 
82
Charlie Martin

Après avoir lu le message 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 le résultat m'a stupéfié.

À l'aide de 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 segment de mémoire, comprises entre 2 et 1024 Mo.

Par exemple, pour créer un segment de mémoire de 2 Mo, j'appelais 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 tas et le nombre maximal de threads est INVERSEMENT proportionnelle.

Ce qui est bizarre.

46
benjismith

Je sais que cette question est assez ancienne mais je veux juste partager mes découvertes.

Mon ordinateur portable est capable de gérer un programme qui génère 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 exécuté ce programme avec 10,000 threads pour 30 minutes continuously, puis mon système était stable et j'ai pu effectuer 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 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 d'exécuter, je définis l'argument jvm -Xmx2048m.

J'espère que ça aide.

36
Shekhar

Le maximum théorique absol est généralement un processus espace d'adressage utilisateur divisé par la taille de la pile de threads (bien qu'en réalité, toute votre mémoire soit réservée aux piles de threads, vous ne le ferez pas. avoir un programme de travail ...).

Ainsi, sous Windows 32 bits, par exemple, où chaque processus a un espace d'adressage utilisateur de 2 Go, ce qui donne à 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 autant de threads dans votre code que de ne pas faire de bêtises (comme en les faisant tous attendre sur le même objet, puis en appelant notifyAll () ...), et (b) si le système d'exploitation le peut. En principe, la réponse à (b) est "oui" si la réponse à (a) est aussi "oui".

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

31
Neil Coffey

Après avoir manipulé la classe DieLikeACode de Charlie, il semble que la taille de la pile de threads Java représente une part énorme du nombre de threads que vous pouvez créer.

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

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'exécuteur de les traiter avec un nombre fixe de threads.

2
Steve K

Je me souviens d’avoir entendu une conversation avec Clojure où il a eu l’occasion de lancer une de ses applications sur une machine spécialisée lors d’un salon commercial avec des milliers de cœurs (9 000?), Et cela les a tous chargés. Malheureusement, je ne trouve pas le lien pour le moment (aide?).

Sur cette base, je pense pouvoir affirmer que le matériel et votre code sont les facteurs limitants, et non la JVM.

2
Ken

Année 2017 ... Cours DieLikeADog.

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

i7-7700 16 Go de RAM

1
Adeptius
0
HUAGHAGUAH

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

Il existe de nombreuses ressources sur cette valeur qui peuvent nécessiter des modifications (telles que Comment augmenter le nombre maximal de threads JVM (Linux 64 bits) ); Cependant, une nouvelle limite est imposée via la limite systemd "TasksMax" qui définit pids.max sur le groupe de contrôle.

Pour les sessions de connexion, le paramètre serTasksMax correspond par défaut à 33% de la limite du noyau pids_max (généralement 12 288) et peut être remplacé dans /etc/systemd/logind.conf.

Pour les services, DefaultTasksMax correspond par défaut à 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
Trent Lloyd

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

  • Configuration matérielle telle que microprocesseur, RAM.
  • Système d'exploitation, qu'il s'agisse de 32 bits ou de 64 bits
  • Code dans la méthode d'exécution. Si le code à l'intérieur de la méthode d'exécution est énorme, alors un objet à thread unique aura davantage de mémoire requise
  • 0
    pgp

    Au moins sur Mac OS X 10.6 32 bits, il existe une limite (2560) imposée par le système d'exploitation. Vérifiez ceci thread de stackoverflow .

    0
    Jifeng Zhang