28 votes

Erreur de mémoire Java : impossible de créer un nouveau thread natif

J'obtiens cette erreur sur mon serveur UNIX, lorsque je lance 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 ...]

Cela se produit chaque fois que j'ai environ 600 fils en cours d'exécution.

J'ai configuré cette variable sur le serveur :

$> ulimit -s 128

Ce qui me semble étrange, c'est le résultat de cette commande, que j'ai exécutée lorsque le bogue s'est produit 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 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 devrait gérer quelque chose comme 5000 threads ou plus. Que se passe-t-il donc, et comment y remédier ?


Edit : voici le résultat 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

J'exécute le script comme un démon depuis init.d, et voici ce que j'exécute :

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 tombé sur cette question de stack overflow avec un test java pour les threads : how-many-threads-can-a-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. Je suis maintenant certain que ce n'est pas normal et que c'est uniquement lié à la configuration de mon serveur. Quelqu'un peut-il m'aider ?


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

J'ai également exécuté ce script sur mon serveur : threads_limits.c et la limite est d'environ 620 fils.

Mon site web est maintenant hors ligne et c'est la pire chose qui aurait pu arriver à mon projet. Je ne sais pas comment recompiler la glibc et tout ça. C'est trop de travail, je pense.

Je suppose que je devrais passer au serveur Windows. Car aucun des paramètres proposés sur cette page n'a apporté de changement : La limite sur mon système se situe entre 600 et 620 threads, quel que soit le programme concerné.

2voto

KQeu Points 11

En rapport avec la réponse du PO, mais je n'ai pas encore la réputation nécessaire pour commenter. J'ai rencontré le même problème en hébergeant Tomcat sur un V-Server .

Tous les moyens standards de vérification du système (quantité/limite de processus, RAM disponible, etc.) indiquaient un système sain, alors que Tomcat plantait avec des variantes de "out of memory / resources / GCThread exceptions".

Il s'avère que certains serveurs V ont un fichier de configuration supplémentaire qui limite la quantité de données autorisées. Threads par processus . Dans mon cas (Ubuntu V -Server avec Strato, Allemagne), cela a même été documenté par l'hébergeur, et la restriction peut être levée manuellement.

Documentation originale de Strato (en allemand) ici : https://www.strato.de/faq/server/prozesse-vs-threads-bei-linux-v-servern/

tl;dr : Comment réparer :

-inspecter la limite de threads par processus :

systemctl show --property=DefaultTasksMax

-Dans mon cas, la valeur par défaut était de 60, ce qui était insuffisant pour Tomcat. Je l'ai changé pour 256 :

vim /etc/systemd/system.conf

Changez la valeur de :

DefaultTasksMax=60

à quelque chose de plus élevé, par exemple 256. (Le connecteur HTTPS de tomcat a un pool de threads par défaut de 200, il devrait donc être d'au moins 200).

Puis redémarrez, pour que les changements prennent effet.

-3voto

Sid Malani Points 1502

Il n'y a plus de mémoire.

Il faut aussi changer ulimit. Si votre système d'exploitation ne donne pas assez de mémoire à votre application, je suppose que -Xmx ne fera aucune différence.

Je suppose que le -Xmx500m n'a aucun effet.

Essayez

u avec -Xmx512m

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X