Java de la Mémoire d'erreur: impossible de créer un thread natif

J'ai cette erreur sur mon serveur UNIX, lors de l'exécution de mon serveur java:

Exception in thread "Thread-0" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)
at [... where ever I launch a new Thread ...]

Il arrive à chaque fois que j'ai environ 600 threads en cours d'exécution.

J'ai mis en place cette variable sur le serveur:

$> ulimit -s 128

Ce qui semble étrange pour moi, c'est le résultat de cette commande, j'ai couru quand le bug a eu lieu la dernière fois:

$> free -m
              total       used       free     shared    buffers     cached
Mem:          2048        338       1709          0          0          0
-/+ buffers/cache:        338       1709
Swap:            0          0          0

Je lance mon serveur java comme ceci:

$> /usr/bin/java -server -Xss128k -Xmx500m -jar /path/to/myJar.jar

Ma version de debian:

$> cat /etc/debian_version
5.0.8

Ma version de java:

$> java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)

Ma question: j'ai lu sur Internet que mon programme doit gérer quelque chose comme 5000 threads ou plus. Donc ce qui se passe, et comment les corriger s'il vous plaît ?


Edit: c'est la sortie de ulimit -a quand j'ouvre un shell:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 794624
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 100000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 794624
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Je lance le script en tant que démon de init.d, et c'est ce que je run:

DAEMON=/usr/bin/java
DAEMON_ARGS="-server -Xss128k -Xmx1024m -jar /path/to/myJar.jar"
ulimit -s 128 && ulimit -n 10240 && start-stop-daemon -b --start --quiet --chuid $USER -m -p $PIDFILE --exec $DAEMON -- $DAEMON_ARGS \
    || return 2

Edit2: je suis venu dans ce débordement de pile question avec un java de test pour les threads: comment plusieurs threads peut-java-vm-support

    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(100); 
                                } catch (Exception e){ 
                                    System.err.println(e); 
                                } 
                            } 
                        } 
                    }).start(); 
            } 
        } 
    } 

Sur mon serveur, le programme se bloque après 613 threads. Maintenant, je suis certain que ce n'est pas normal, et uniquement lié à ma configuration de serveur. Quelqu'un peut-il aider s'il vous plaît ?


Edit 3:
Je suis tombé sur cet article, et beaucoup d'autres, expliquant que linux ne peut pas créer de 1000 threads, mais les gars, vous me dites que vous pouvez le faire sur votre système. Je ne comprends pas.

J'ai aussi couru à ce script sur mon serveur: threads_limits.c et la limite est de l'ordre de 620 fils.

Mon site est maintenant en mode hors connexion et c'est la pire chose qui puisse arriver à mon projet.
Je ne sais pas comment recompiler glibc et ce genre de choses. C'est trop de travail de l'omi.

Je suppose que je devrais passer à windows server. Car aucun des paramètres proposés sur cette page ne faire aucun changement: La limite de mon système est entre 600 et 620 fils, peu importe le programme.

  • C'est un serveur de jeu. J'ai ouvert 2 threads pour chaque client: 1 pour le protocole TCP-lire, et 1 pour le protocole TCP-écrire. Le serveur se bloque quand j'arrive à 300 clients, mais j'ai des tonnes de mémoire, alors pourquoi ?
  • Roach: Pourquoi pas? Véritable matériel de serveur peuvent le taux de désabonnement avec d'assez grandes quantités de threads sans trop de problèmes, si les paramètres sont corrects.
  • Et quelles en seraient les paramètres corrects être, s'il vous plaît ?
  • Parce que le changement de contexte et les frais généraux de le faire est horrible et pas nécessaire?
  • Roach: nous sommes en cours d'exécution autour de 2000 à 4000 threads, la plupart d'entre elles sont actives, et la charge de serveur est d'environ 2% à 5% (sur un 4-core Xeon). Bien sûr, cela est spécifique à notre serveur et le logiciel de configuration.
  • Aucune raison pourquoi vous êtes plafonnement de la -Xmx à une simple 500M pour une haute performance du serveur d'application et que trop sur une version 64 bits de la VM?
  • La raison en est qu'il ne semble pas changer quoi que ce soit puisque je ne suis pas d'atteindre cette limite.
  • Droit, mon point est, avez-vous essayé avec différentes valeurs de Xmx comme 4GiB? Le nombre de threads dans ce cas tombe? Aussi, vous pouvez poster à la sortie de ulimit -a?
  • Je ne peux pas poster la sortie puisqu'il est situé dans un daemon script init.d, mais j'ai soulevé à chaque valeur de la limite, sauf les fils de la pile de la taille abaissée à 128, et c'est toujours de s'écraser à 600 fils.
  • oui, j'ai essayé de chaque valeur possible pour xmx mais ça ne change quoi que ce soit depuis l'application serveur qui consomme moins de mémoire que 200 mo de même pour 300 clients
  • Il y avait des tests qui ont montré de meilleures performances avec Java IO comparativement à NIO - et contrairement à la sagesse générale ("nio beaucoup plus rapide que io") que mec effectivement fourni des repères pour ses revendications. Il est donc de loin pas que claire. La page est en bas de l'atm, mais il y a un google docs version:
  • cont. plutôt long lien
  • Vous avez raison, cela ne semble pas Java spécifique, mais plus d'un problème de config. Pour essayer quelques petites choses: vous pouvez exécuter le même code sans impliquer init.d? c'est à dire une plaine simple ulimit -s 128; ulimit -n 10240; java -server -Xss128k -Xmx1G -jar /path/to/myJar.jar à la bash shell? Parce qu'il semble que votre ulimit changements ne sont pas pris en charge par votre java processus de...
  • Ce pourrait être votre coupable: "la taille de la pile (kbytes, -s) 10240" (à Partir de votre ulimit -a output). C'est 10megabytes de la pile par thread. Essayez de modifier votre " /etc/security/limits.conf' et de définir la taille de la pile et d'autres paramètres. Je ne pense pas que ulimit-changements sont ramassés dans la même session (mais pas sûr), mais la modification de /etc/security/limits.conf doit être permanente (nécessite au moins démarrer une nouvelle session, qui charge la modification des limites.conf, ou dans le pire des cas, un redémarrage à chaque fois que le fichier est modifié, ne me souviens plus qui). Faire une sauvegarde de la configuration d'origine avant de le modifier
  • ulimit changements sont repris dans le même bash session. Le problème est peut-être la manière dont le démon est ramasser ces limites
  • Ce noyau que vous utilisez? Toute sortie de dmesg ?
  • J'ai essayé d'exécuter la commande dans un bash session et avait le même problème
  • J'ai déjà essayé avec cette limite.fichier conf et toujours le même limite exacte de 600 fils
  • J'utilise Debian 5.0.8 et la commande dmesg sorties de rien.
  • 1) Avez-vous d'exécuter le programme dans edit2 directement à partir de la promt où vous avez tapé ulimit-a ? J'ai copié votre établissement et je n'ai aucun problème. 2) Quelle est la commande uname-a-dire?
  • Oui j'ai exécuté la edit2 directement à partir de l'invite de commandes. uname -a retourne Linux de801.ispfr.net 2.6.18-028stab085.5 #1 SMP Thu Apr 14 15:06:33 MSD 2011 x86_64 GNU/Linux
  • Voir mon post, vérifiez que vous avez NTPL et pas le vieux et obsolète "Linux Threads" qui pourrait gérer à 1500 threads ou plus.
  • laissez-nous continuer cette discussion dans le chat
  • Merci pour votre aide. Je suis sur le chat.

InformationsquelleAutor Joel | 2011-11-20