2008-09-22 8 views
7

Ich habe ein Problem auf einem Testcomputer mit Red Hat Linux (Kernel-Version 2.4.21-37.ELsmp) mit Java 1.6 (1.6.0_02 oder 1.6.0_04)). Sobald eine bestimmte Anzahl von Threads in einer einzelnen Thread-Gruppe erstellt wurde, ist das Betriebssystem nicht mehr in der Lage oder nicht mehr dazu in der Lage zu sein, weitere Threads zu erstellen.Niedrige Java-Einzelprozess-Thread-Grenze in Red Hat Linux

Dies scheint spezifisch für die Java-Erstellung von Threads zu sein, da das C-Thread-Limit-Programm in der Lage war, etwa 1.5k Threads zu erstellen. Darüber hinaus passiert dies nicht mit einer Java 1.4 JVM ... es kann über 1.4k Threads erstellen, obwohl sie offensichtlich in Bezug auf das Betriebssystem anders gehandhabt werden.

In diesem Fall ist die Anzahl der Threads, die abgeschnitten werden, lediglich 29 Threads. Dies ist mit einem einfachen Java-Programm testbar, das nur Threads erstellt, bis ein Fehler auftritt, und dann die Anzahl der erstellten Threads ausgibt. Der Fehler ist ein

java.lang.OutOfMemoryError: unable to create new native thread

Dies scheint von Dingen wie der Anzahl der Threads, die von anderen Prozessen oder Benutzern verwendet werden, oder der Gesamtspeichermenge, die das System zu der Zeit verwendet, nicht betroffen zu sein. JVM-Einstellungen wie Xms, Xmx und Xss scheinen auch nichts zu ändern (was zu erwarten ist, wenn man bedenkt, dass das Problem mit der Erstellung eines nativen OS-Threads zu tun zu haben scheint).

Die Ausgabe von „ulimit -a“ ist wie folgt:

 
core file size  (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
file size    (blocks, -f) unlimited 
max locked memory  (kbytes, -l) 4 
max memory size  (kbytes, -m) unlimited 
open files     (-n) 1024 
pipe size   (512 bytes, -p) 8 
stack size   (kbytes, -s) 10240 
cpu time    (seconds, -t) unlimited 
max user processes   (-u) 7168 
virtual memory  (kbytes, -v) unlimited 

Der Benutzer Prozess Grenze scheint nicht das Problem zu sein. Die Suche nach Informationen darüber, was falsch laufen könnte, ist nicht groß geworden, aber this post scheint darauf hinzuweisen, dass zumindest einige Red Hat-Kernel einen Prozess auf 300 MB Speicher für Stack und 10 MB pro Thread für Stack begrenzen das Problem könnte da sein (obwohl es seltsam und unwahrscheinlich erscheint).

Ich habe versucht, die Stapelgröße mit „ulimit -s“ zu testen, dies zu ändern, aber ein anderer Wert als 10240 und die JVM mit einem Fehler von nicht startet: ich in der Regel erhalten

Error occurred during initialization of VM 
Cannot create VM thread. Out of system resources.

können um Linux, aber ich weiß wirklich nicht viel über die Systemkonfiguration, und ich konnte nichts finden, das speziell auf diese Art von Situation eingeht. Irgendwelche Ideen, welche System- oder JVM-Einstellungen dies verursachen könnten, würden geschätzt werden.

Bearbeitungen: Beim Ausführen des von plinth erwähnten Thread-Limit-Programms gab es keinen Fehler, bis versucht wurde, den 1529. Thread zu erstellen.

Das Problem trat auch nicht mit einer 1.4 JVM auf (tritt bei 1.6.0_02 und 1.6.0_04 JVMs auf, kann zur Zeit nicht mit einer 1.5 JVM getestet werden).

Der Code für den Thread-Test verwende ich wie folgt:

public class ThreadTest { 

    public static void main(String[] pArgs) throws Exception { 

     try { 
     // keep spawning new threads forever 
     while (true) { 
      new TestThread().start(); 
     } 
     } 
     // when out of memory error is reached, print out the number of 
     // successful threads spawned and exit 
     catch (OutOfMemoryError e) { 
     System.out.println(TestThread.CREATE_COUNT); 
     System.exit(-1); 
     } 
    } 

    static class TestThread extends Thread { 
     private static int CREATE_COUNT = 0; 
     public TestThread() { 
     CREATE_COUNT++; 
     } 
     // make the thread wait for eternity after being spawned 
     public void run() { 
     try { 
      sleep(Integer.MAX_VALUE); 
     } 
     // even if there is an interruption, dont do anything 
     catch (InterruptedException e) { 
     } 
     } 
    } 
} 

Wenn Sie dies mit einem 1.4 JVM läuft es hängen, wenn es keine weiteren Threads nicht erstellen und benötigen einen Kill - 9 (zumindest hat es für mich getan).

Mehr Edit:

Es stellt sich heraus, dass das System, das das Problem aufweist, ist die Linuxthreads unter Verwendung von Threading-Modell, während ein anderes System, das gut funktioniert ist das NPTL Modell.

+0

nur eine kleine Bemerkung am Rande für alle neuen Programmierer will-zu-sein: nie 'verwenden while (true)' überall außer für Schulprojekte und private Experimente und _NEVER_ Tausende von Threads erstellen, Ihre App höchstwahrscheinlich hat ernsthafte Fehler, wenn es tut - oder Ihr Anwendungsdesign ist fehlerhaft. Sayin .. – specializt

Antwort

4

Aktualisierung des Kernels auf eine neuere Version (2.6.etwas) mit NPTL-Threading behoben.

4

Haben Sie sich this resource angesehen? Es besagt, dass Sie Thread-Limit ausführen können, um die maximale Anzahl von Threads zu finden, und können es optimieren, indem Sie glibc kompilieren.

+0

Seltsamerweise konnte Thread-Limit 1528 Threads vor dem Scheitern erstellen. Hmm. – ColinD

0

Können Sie es mit der JRockit JVM versuchen? IIRC, hatte es ein anderes Threading-Modell als die Aktie Sun JVM.

0

Die Einstellungen in /etc/security/limits.d/90-nproc.conf überschreiben möglicherweise Ihre /etc/security/limits.conf Einstellungen. Dies kann dazu führen, dass das System anders reagiert, wie in ulimit -u gezeigt.

https://bugzilla.redhat.com/show_bug.cgi?id=823030

Verwandte Themen