it-swarm.com.de

"Java.lang.OutOfMemoryError: Neuer nativer Thread kann nicht erstellt werden"

Wir bekommen "Java.lang.OutOfMemoryError : unable to create new native Thread "auf 8 GB RAM VM nach 32k-Threads (ps -eLF | grep -c Java)

"top" and "free -m" shows 50% free memory available. JDk ist 64 Bit und wurde sowohl mit HotSpot als auch mit JRockit.Server unter Linux 2.6.18 getestet

Wir haben auch versucht OS stack size (ulimit -s) Zwicken und max Prozess (ulimit -u) Grenzen, limit.conf Anstieg aber alles umsonst.

Wir haben auch fast alle möglichen Kombinationen von Heap-Größen ausprobiert, um sie niedrig, hoch usw. zu halten.

Das Skript, das wir zum Ausführen der Anwendung verwenden, ist 

/opt/jrockit-jdk1.6/bin/Java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties

Danke für die Antwort.

Wir haben versucht, /etc/security/limits.conf und ulimit zu bearbeiten, aber immer noch dasselbe

[[email protected] ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 72192
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
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) 72192
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
104
Deepak Tewani

Dies ist kein Speicherproblem, auch wenn der Name der Ausnahme sehr nahelegt, sondern ein Betriebssystemproblem. Ihnen stehen keine nativen Threads zur Verfügung, d. H. Wie viele Threads das Betriebssystem Ihrer JVM zulässt. 

Dies ist ein ungewöhnliches Problem, da Sie selten so viele benötigen. Haben Sie viel bedingungsloses Thread-Laichen, wo die Threads sollten, aber nicht enden? 

Möglicherweise sollten Sie die Verwendung von Callable/Runnables unter der Kontrolle eines Executors neu schreiben, wenn dies überhaupt möglich ist. Es gibt viele Standard-Executoren mit verschiedenen Verhaltensweisen, die Ihr Code leicht steuern kann.

(Es gibt viele Gründe, warum die Anzahl der Threads begrenzt ist, aber sie variieren von Betriebssystem zu Betriebssystem.)

Beim Ladenstest ist das gleiche Problem aufgetreten. Der Grund dafür ist, dass JVM keinen neuen Java-Thread mehr erstellen kann. Unten ist der JVM-Quellcode 

if (native_thread->osthread() == NULL) {    
// No one should hold a reference to the 'native_thread'.    
    delete native_thread;   
if (JvmtiExport::should_post_resource_exhausted()) {      
    JvmtiExport::post_resource_exhausted(        
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
        JVMTI_RESOURCE_EXHAUSTED_THREADS, 
        "unable to create new native thread");    
    } THROW_MSG(vmSymbols::Java_lang_OutOfMemoryError(), "unable to create new native thread");  
} Thread::start(native_thread);`

Grundursache: JVM löst diese Ausnahme aus, wenn JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR (Ressourcen erschöpft (bedeutet Speicher Erschöpft)) oder JVMTI_RESOURCE_EXHAUSTED_THREADS (Gewinde erschöpft).

In meinem Fall erstellt Jboss zu viele Threads, um die Anforderung zu bedienen, aber alle Threads sind blockiert. Aus diesem Grund ist JVM mit Threads sowie mit Arbeitsspeicher erschöpft (jeder Thread enthält Arbeitsspeicher, der nicht freigegeben wird, da jeder Thread blockiert ist). 

Analysiert wurden die Java-Thread-Dumps, die beobachtet wurden, und fast 61K-Threads wurden durch eine unserer Methoden blockiert, was dieses Problem verursacht. Unten ist der Teil des Thread-Dumps 

"SimpleAsyncTaskExecutor-16562" #38070 prio=5 os_prio=0 tid=0x00007f9985440000 nid=0x2ca6 waiting for monitor entry [0x00007f9d58c2d000]
   Java.lang.Thread.State: BLOCKED (on object monitor)
10
Madhu Cheepati

Es ist wahrscheinlich, dass Ihr Betriebssystem die Anzahl der Threads, die Sie erstellen möchten, nicht zulässt oder dass Sie in der JVM ein gewisses Limit erreichen. Besonders wenn es sich um eine runde Zahl wie 32k handelt, ist ein Limit der einen oder anderen Art höchstwahrscheinlich ein Täter.

Bist du sicher, dass du wirklich 32k Threads brauchst? Die meisten modernen Sprachen unterstützen Pools wiederverwendbarer Threads - ich bin sicher, Java hat auch etwas (wie ExecutorService, wie der Benutzer Jesper erwähnt hat). Vielleicht können Sie Threads aus einem solchen Pool anfordern, anstatt manuell neue zu erstellen.

Ich würde empfehlen, sich auch die Thread-Stack-Größe anzusehen und zu prüfen, ob weitere Threads erstellt werden. Die Standard-Thread-Stack-Größe für JRockit 1.5/1.6 beträgt 1 MB für 64-Bit VM unter Linux. 32-KByte-Threads erfordern eine beträchtliche Menge an physischem und virtuellem Speicher, um diese Anforderung zu erfüllen. 

Versuchen Sie, die Stack-Größe als Ausgangspunkt auf 512 KB zu reduzieren, und prüfen Sie, ob dadurch mehr Threads für Ihre Anwendung erstellt werden können. Ich empfehle auch, die horizontale Skalierung zu untersuchen, z. Aufteilen der Anwendungsverarbeitung auf mehr physische oder virtuelle Maschinen.

Bei Verwendung einer 64-Bit-VM hängt der tatsächliche Grenzwert von der Verfügbarkeit des physischen und virtuellen Arbeitsspeichers des Betriebssystems sowie den Parametern des Betriebssystems (z. B. ulimitc) ab. Ich empfehle auch den folgenden Artikel als Referenz:

OutOfMemoryError: Neuer nativer Thread kann nicht erstellt werden. Problem Demystified

5
P-H

Ich hatte das gleiche Problem aufgrund von Geisterprozessen, die bei der Verwendung von top in bash nicht auftauchten. Dies hinderte die JVM daran, mehr Threads zu erzeugen.

Für mich wurde das Problem gelöst, wenn alle Java-Prozesse mit jps aufgelistet wurden (führen Sie einfach jps in Ihrer Shell aus) und beenden Sie sie separat mit dem kill -9 pid bash-Befehl für jeden Ghost-Prozess.

Dies kann in einigen Szenarien hilfreich sein.

3
mac7

Sie haben die Möglichkeit, dem Java.lang.OutOfMemoryError: Unable to create new native thread gegenüberzustellen, wenn die JVM vom Betriebssystem nach einem neuen Thread fragt. Wenn das zugrunde liegende Betriebssystem keinen neuen nativen Thread zuordnen kann, wird dieser OutOfMemoryError ausgelöst. Der genaue Grenzwert für native Threads ist sehr plattformabhängig. Daher wird empfohlen, diese Grenzwerte anhand eines Tests zu ermitteln, der dem folgenden Link-Beispiel ähnlich ist. Im Allgemeinen durchläuft die Situation, die Java.lang.OutOfMemoryError: Unable to create new native thread verursacht, die folgenden Phasen:

  1. Ein neuer Java-Thread wird von einer Anwendung angefordert, die in der JVM .__ ausgeführt wird 
  2. Native JVM-Code gibt die Anforderung zum Erstellen eines neuen nativen Threads an das Betriebssystem weiter. Das Betriebssystem versucht, einen neuen nativen Thread zu erstellen, für den Dem Thread Speicher zugewiesen werden muss 
  3. Das Betriebssystem wird die native Speicherzuweisung ablehnen, entweder weil die 32-Bit-Java-Prozessgröße, _ ihren Speicheradressenraum - z. (2-4) GB-Prozessgröße Limit wurde erreicht - oder der virtuelle Speicher des Betriebssystems ist Vollständig erschöpft 
  4. Der Java.lang.OutOfMemoryError: Es kann kein neuer nativer Thread-Fehler erstellt werden.

Referenz: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread

1

ihre JBoss-Konfiguration hat einige Probleme: /opt/jrockit-jdk1.6/bin/Java -Xms512m -Xmx512m Xms und Xmx beschränken Ihre JBoss-Speichernutzung auf den konfigurierten Wert, also von den 8 GB, die Sie haben Der Server verwendet nur 512M + etwas mehr für seinen eigenen Zweck. Erhöhen Sie diese Anzahl. Denken Sie daran, einige für das Betriebssystem und andere Dinge frei zu lassen, die dort ausgeführt werden. Möglicherweise haben Sie es trotz des unsavourösen Codes ausgeführt sei auch nett, wenn du kannst.

1
user3390284

Wenn Ihr Job aufgrund von OutOfMemmory für Knoten fehlschlägt, können Sie die Anzahl der maximalen Karten und Reduzierungen sowie die JVM-Optionen für jeden Knoten abfragen. mapred.child.Java.opts (der Standardwert ist 200Xmx) muss normalerweise auf der Grundlage der für Ihre Datenknoten spezifischen Hardware erhöht werden.

Dieser Link könnte hilfreich sein ... Bitte überprüfen

1
Pavan Kumar K

Ich hatte das gleiche Problem und es stellte sich heraus, dass eine Java-API nicht ordnungsgemäß verwendet wurde. Ich habe einen Builder in einer Stapelverarbeitungsmethode initialisiert, die nicht mehr als einmal initiiert werden sollte.

Grundsätzlich habe ich so etwas gemacht:

for (batch in batches) {
    process_batch(batch)
}

def process_batch(batch) {
    var client = TransportClient.builder().build()
    client.processList(batch)
}

wenn ich das hätte tun sollen:

for (batch in batches) {
    var client = TransportClient.builder().build()
    process_batch(batch, client)
}

def process_batch(batch, client) {
    client.processList(batch)
}
0
anthonybell

Wenn jvm über systemd gestartet wird, kann es in einigen Linux-Betriebssystemen zu einer Beschränkung von maxTasks pro Prozess kommen (Tasks bedeuten tatsächlich Threads).

Sie können dies überprüfen, indem Sie "Dienststatus" ausführen und prüfen, ob es ein maxTasks-Limit gibt. Wenn dies der Fall ist, können Sie es entfernen, indem Sie /etc/systemd/system.conf bearbeiten und eine Konfiguration hinzufügen: DefaultTasksMax = infinity

0
Clement.Xu

Dieser Fehler kann aus zwei Gründen auftreten:

  • Im Speicher ist kein Platz für neue Threads.

  • Die Anzahl der Threads überschreitet die Betriebssystemgrenze.

Ich bezweifle, dass die Anzahl der Threads die Grenze für den Java-Prozess überschritten hat

Möglicherweise besteht also die Möglichkeit, dass das Problem wegen des Gedächtnisses ist. Ein einziger Punkt ist zu berücksichtigen 

threads werden nicht im JVM-Heap erstellt. Sie werden außerhalb von .__ erstellt. der JVM-Haufen. Wenn also weniger Speicherplatz im RAM vorhanden ist, nach der JVM Bei der Heap-Zuordnung wird die Anwendung in .__ ausgeführt. "Java.lang.OutOfMemoryError: Neuer nativer Thread kann nicht erstellt werden".

Eine mögliche Lösung besteht darin, den Heapspeicher zu reduzieren oder die Gesamtgröße des RAMs zu erhöhen 

0
Maverick

Um herauszufinden, welche Prozesse Threads erstellen, versuchen Sie Folgendes:

ps huH

Normalerweise leite ich die Ausgabe in eine Datei um und analysiere sie offline (ist die Anzahl der Threads für jeden Prozess wie erwartet oder nicht). 

0
user8521771