Combien de threads une VM Java peut-elle supporter?

combien de threads une VM Java peut-elle supporter? Est-ce à varier selon le fournisseur? par système d'exploitation? d'autres facteurs?

181
demandé sur Steve Kuo 2009-04-18 19:06:45

13 réponses

cela dépend du CPU que vous utilisez, du système D'exploitation, de ce que les autres processus font, 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), l'ensemble de 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 accueillir 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 les Threads font et avoir une pile pour chaque Thread. N'importe quelle machine avec un CPU moderne (les plus récentes générations de AMD ou Intel) et avec 1 - 2 Gig de mémoire (selon OS) peut facilement soutenir une JVM avec milliers de fils.

Si vous avez besoin d'une réponse spécifique que cela, votre meilleur pari est de profil.

148
répondu Eddie 2009-04-18 15:16:04

Euh, beaucoup.

Il y a plusieurs paramètres ici. La VM spécifique, plus il y a généralement des paramètres de temps d'exécution sur la VM aussi bien. C'est un peu tirée par le système d'exploitation: quel soutien l'OS sous-jacent ont pour fils et quelles sont les limites met-il sur eux? Si la VM utilise réellement des threads au niveau OS, la bonne vieille chose fil rouge / fil vert.

ce que" soutien " signifie est une autre question. Si vous écrivez un Java programme qui est quelque chose comme

   class DieLikeADog {
         public static void main(String[] argv){
             for(;;){
                new Thread(new SomeRunaable).start();
             }
         }
    }

(et ne vous plaignez pas de petits détails de syntaxe, je suis sur ma première tasse de café) alors vous devriez certainement vous attendre à obtenir des centaines ou des milliers de fils en cours d'exécution. Mais créer un Thread est relativement cher, et scheduler overhead peut devenir intense; il n'est pas clair que vous pourriez avoir ces threads faire quelque chose d'utile.

mise à Jour

OK, 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 eu

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
répondu 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 de tas fait une différence dans le nombre de fils que vous pouvez créer, et j'ai été totalement stupéfait 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 importe vraiment. Mais la relation entre la taille du tas et le nombre maximum de fils est inversement proportionnelle.

ce qui est bizarre.

44
répondu 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 le programme qui produit 25,000 threads et tous ces threads écrire certaines 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 mon système était stable et j'ai été en mesure 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 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, j'ai placé l'argument jvm -Xmx2048m .

j'Espère que ça aide.

33
répondu Shekhar 2013-04-21 08:24:39

le maximum théorique absolu est généralement un processus espace d'adresse de l'utilisateur divisé par la taille de la pile de thread (bien qu'en réalité, si toute votre mémoire est réservée pour les piles de thread, vous n'aurez pas de programme de travail...).

donc sous les fenêtres 32 bits, par exemple, où chaque processus a une adresse d'utilisateur de l'espace de 2 Go, donnant à chaque thread une taille de pile de 128K, 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.

donc, je pense que vous êtes essentiellement dans la question de 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".

Soit dit en passant ,vous pouvez spécifier la taille de la pile dans le constructeur du Thread ; vous n'avez pas besoin de (et probablement ne devriez pas) déconner avec les paramètres VM pour cela.

29
répondu Neil Coffey 2009-04-18 20:08:53

je me rappelle avoir entendu un Clojure parler où il a pu lancer une de ses applications sur une machine spécialisée à un salon avec des milliers de cœurs (9000?), et il est chargé de tous les. Malheureusement, je ne trouve pas le lien En ce moment (AIDE?).

basé sur cela, je pense qu'il est sûr de dire que le matériel et votre code sont les facteurs limitatifs, pas le JVM.

2
répondu 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 Java thread est une énorme partie du nombre de fils que vous pouvez créer.

-Xss jeu java la taille de la pile

par exemple

java-Xss100k DieLikeADog

mais, Java a le exécuteur interface. Je voudrais l'utiliser, vous sera capable de soumettre des milliers de tâches exécutables, et aura L'exécuteur traiter ces tâches avec un nombre fixe de threads.

2
répondu Steve K 2009-04-18 17:54:40

au moins sur Mac OS X 10.6 32bit, il y a une limite (2560) par le système d'exploitation. Cochez cette case filetage de débordement .

0
répondu Jifeng Zhang 2017-05-23 12:26:25

le nombre Maximum de threads dépend des choses suivantes:

  • configuration matérielle comme microprocesseur, RAM.
  • système D'exploitation comme s'il est 32-bit ou 64-bit
  • Code dans la méthode run. Si le code à l'intérieur de la méthode run est énorme alors un seul objet thread aura besoin de plus de mémoire
  • 0
    répondu pgp 2013-05-29 04:05:53

    informations Supplémentaires pour moderne (systemd) les systèmes linux.

    il existe de nombreuses ressources à ce sujet de valeurs qui peuvent avoir besoin de retouches (comme comment augmenter le nombre maximum de threads JVM (Linux 64bit) ); toutefois, une nouvelle limite est imposée par le biais de la limite systemd" TasksMax " qui définit les pid.max sur les cgroup.

    pour les sessions de connexion le UserTasksMax par défaut est 33% de la limite du noyau pids_max (habituellement 12,288) et peut être modifié dans /etc/systemd/logind.conf.

    pour les services DefaultTasksMax par défaut est de 15% de la limite du noyau pids_max (habituellement 4,915). Vous pouvez l'Annuler pour le service en définissant TasksMax dans "systemctl edit" ou mettre à jour DefaultTasksMax dans /etc/systemd/system.conf

    0
    répondu 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 fil natif

    i7-7700 16 Go ram

    0
    répondu Adeptius 2017-10-11 20:46:13

    vous pouvez traiter n'importe quel nombre de threads; il n'y a aucune limite. J'ai passé le code suivant en regardant un film et en utilisant NetBeans, et il a fonctionné correctement/sans arrêter la machine. Je pense que vous pouvez garder encore plus de fils que ce programme ne le fait.

    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
    répondu Anil Pal 2011-11-25 04:49:28