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 simple500M
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
comme4GiB
? Le nombre de threads dans ce cas tombe? Aussi, vous pouvez poster à la sortie deulimit -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 simpleulimit -s 128; ulimit -n 10240; java -server -Xss128k -Xmx1G -jar /path/to/myJar.jar
à labash
shell? Parce qu'il semble que votreulimit
changements ne sont pas pris en charge par votrejava
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êmebash
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
retourneLinux 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.
Vous devez vous connecter pour publier un commentaire.
Viens de recevoir les informations suivantes: C'est une limitation imposée par mon hébergeur. Cela n'a rien à voir avec de la programmation, ou linux.
Le système d'exploitation (Debian Linux dans ce cas) ne permet pas la création de plus de threads. Voir ici comment faire pour augmenter le montant maximum: Nombre Maximum de threads par processus dans Linux?
Cela dépend des limites fixées à l'OS, le montant des processus en cours d'exécution, etc. Avec des paramètres appropriés, vous pouvez atteindre aisément que le nombre de threads. Je suis sur Ubuntu sur mon ordinateur, et je peux créer autour de 32000 threads avant de frapper à la limite sur un seul programme Java avec tous mes "normal trucs" en cours d'exécution sur le fond (ce qui a été fait avec un programme de test qui venez de créer fils qui est allé dormir immédiatement dans une boucle infinie). Naturellement, cette quantité de fils en train de faire quelque chose aurait probablement brûler la consommation de matériel à un arrêt assez rapide.
free -m
? N'est-ce pas dire que j'ai 75% de mémoire libre ?Pouvez-vous essayer la même commande avec une plus petite taille de la pile "-Xss64k" et de passer sur les résultats ?
Je commence à soupçonner que "Native Posix Thread Library" est manquant.
Devrait afficher quelque chose comme:
Si non, l'installation de Debian est foiré. Je ne suis pas sûr de la façon de corriger cela, mais l'installation d'Ubuntu Server semble comme un bon coup...
pour ulimit -n 100000; (ouvrir fd:s) le programme suivant doit être capable de gérer 32.000 threads ou plus.
Essayer:
getconf GNU_LIBPTHREAD_VERSION
estNPTL 2.7
.Votre JVM ne parvient pas à allouer de la pile ou de quelques autres par-fil de la mémoire. L'abaissement de la taille de la pile avec
-Xss
permettra d'augmenter le nombre de threads que vous pouvez créer avant OOM se produit (mais JVM ne vous permettra pas de définir arbitrairement petite taille de la pile).Vous pouvez confirmer que c'est le problème en voyant comment le nombre de threads créés modifier comme vous tordre
-Xss
ou en exécutant strace sur votre JVM (vous aurez presque certainement voir unmmap()
retourENOMEM
juste avant une exception est levée).Vérifier votre
ulimit
sur la taille virtuelle, c'est à direulimit -v
. L'augmentation de cette limite devrait vous permettre de créer plus de threads avec la même taille de la pile. Notez que résidente de limite de taille (ulimit -m
) est inefficace dans le noyau Linux actuel.Aussi, en abaissant
-Xmx
pouvez nous aider en laissant plus de mémoire pour les piles de threads.Sa va de mémoire.
Aussi besoin de changer ulimit. Si votre système d'exploitation ne donnez pas à votre application assez de mémoire -Xmx, je suppose, ne fera aucune différence.
Je suppose que l'-Xmx500m est ne pas avoir d'effet.
Essayer