Java Memory error: impossible de créer un nouveau thread natif

je reçois 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 ...]

cela arrive à chaque fois que j'ai environ 600 threads 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 bug 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 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. Alors que se passe-t-il, et comment réparer 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 cours le script en tant que démon d'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: j'ai rencontré cette question de débordement de pile 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 s'écrase après 613 threads. Maintenant je suis certain que ce n'est pas normal, et seulement lié à la configuration de mon serveur. Est-ce que quelqu'un peut aider s'il vous plaît ?


Modifier 3: Je suis tombé sur cet article, et bien 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 aussi lancé ce script sur mon serveur: threads_limits.c et la limite est d'environ 620 threads.

mon site web est maintenant hors ligne et c'est la pire chose qui puisse arriver à mon projet. Je ne sais pas comment recompiler glibc et tout ça. C'est trop de travail de l'omi.

je suppose que je devrais passer à Windows server. Parce qu'aucun des paramètres proposés sur cette page n'a fait de changement: la limite sur mon système est entre 600 et 620 threads, peu importe le programme impliqué.

25
demandé sur Community 2011-11-20 21:11:36
la source

6 ответов

vient de recevoir l'information suivante: il s'agit d'une limitation imposée par mon hébergeur. Cela n'a rien à voir avec la programmation, ou linux.

12
répondu Joel 2011-11-22 16:10:53
la source

le système d'exploitation sous-jacent (Debian Linux dans ce cas) ne permet pas au processus de créer plus de threads. Voir ici comment augmenter la quantité maximum: nombre Maximum de threads par processus sous Linux?

j'ai lu sur Internet que mon programme devrait gérer quelque chose comme 5000 fils ou plus.

cela dépend des limites fixées à L'OS, du nombre de processus en cours, etc. Avec les paramètres corrects vous pouvez facilement atteindre que beaucoup de threads. J'exécute Ubuntu sur mon propre ordinateur, et je peux créer environ 32000 threads avant de frapper la limite sur un seul programme Java avec tous mes "trucs normaux" courant sur l'arrière-plan (cela a été fait avec un programme de test qui vient de créer des threads qui sont allés dormir immédiatement dans une boucle infinie). Naturellement, que la quantité élevée de threads réellement faire quelque chose serait probablement screech matériel de consommation à un arrêt assez rapide.

7
répondu esaj 2017-05-23 15:18:33
la source

pouvez-vous essayer la même commande avec une plus petite taille de pile "- Xss64k" et transmettre les résultats ?

3
répondu souser 2011-11-20 21:45:21
la source

je commence à soupçonner que" Bibliothèque natif de fils Posix " est manquant.

>getconf GNU_LIBPTHREAD_VERSION

devrait sortir quelque chose comme:

NPTL 2.13

si ce n'est pas le cas, L'installation Debian est en panne. Je ne suis pas sûr de savoir comment corriger cela, mais installer le serveur Ubuntu semble être un bon choix...

pour ulimit -n 100000; (ouvrir fd:s) le programme suivant doit être capable de gérer 32.000 threads.

l'Essayer:

package test;

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

public class Test {

    final static Semaphore ss = new Semaphore(0);


    static class TT implements Runnable {

        @Override
        public void run() {
            try {
                Socket t = new Socket("localhost", 47111);
                InputStream is = t.getInputStream();
                for (;;) {
                    is.read();
                }

            } catch (Throwable t) {
                System.err.println(Thread.currentThread().getName() + " : abort");
                t.printStackTrace();
                System.exit(2);
            }

        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {

            Thread t = new Thread() {
                public void run() {
                    try {
                        ArrayList<Socket> sockets = new ArrayList<Socket>(50000);
                        ServerSocket s = new ServerSocket(47111,1500);
                        ss.release();

                        for (;;) {
                            Socket t = s.accept();
                            sockets.add(t);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.exit(1);

                    }
                }
            };


            t.start();
            ss.acquire();


            for (int i = 0; i < 30000; i++) {

                Thread tt = new Thread(new TT(), "T" + i);
                tt.setDaemon(true);
                tt.start();
                System.out.println(tt.getName());
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    return;
                }
            }

            for (;;) {
                System.out.println();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    return;
                }
            }

        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}
2
répondu KarlP 2011-11-21 23:34:03
la source

votre JVM ne parvient pas à allouer la pile ou une autre mémoire par thread. Abaisser la taille de la pile avec -Xss aidera à augmenter le nombre de threads que vous pouvez créer avant que OOM se produise (mais JVM ne vous laissera pas définir arbitrairement la petite taille de la pile).

vous pouvez confirmer que c'est le problème en voyant comment le nombre de threads créés change alors que vous tweak -Xss ou en lançant strace sur votre JVM (vous verrez presque certainement un mmap() retour "à la 151930920" juste avant une exception est levée).

cochez également votre ulimit sur la taille virtuelle, i.e. ulimit -v . Augmenter cette limite devrait vous permettre de créer plus de threads avec la même taille de pile. Notez que resident set size limit ( ulimit -m ) est inefficace dans le noyau Linux actuel .

aussi, en abaissant -Xmx peut aider en laissant plus de mémoire pour les piles de fil.

1
répondu Adam Zalcman 2017-05-23 13:31:02
la source

ça sort de la mémoire.

doit également changer ulimit. Si votre système D'exploitation ne fournit pas assez de mémoire à votre application-Xmx, je suppose que cela ne fera aucune différence.

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

Essayer

ulimit-m 512m avec-Xmx512m

-3
répondu Sid Malani 2011-11-20 21:22:56
la source

Autres questions sur