Wir bekommen "java.lang.OutOfMemoryError : unable to create new native Thread
"auf 8 GB RAM VM nach 32k Threads (ps -eLF | grep -c Java)
Jedoch "top" and "free -m" shows 50% free memory available
. JDk ist 64-Bit und wird sowohl mit HotSpot als auch mit JRockit versucht. Server hat Linux 2.6.18
Wir haben auch versucht, die OS stack size (ulimit -s)
Grenzen zu optimieren und zu maximieren (ulimit -u), limit.conf zu erhöhen, aber alles umsonst.
Außerdem haben wir fast alle möglichen Kombinationen von Heap-Größen ausprobiert, um sie niedrig, hoch usw. zu halten.
Das Skript, mit dem wir die Anwendung ausführen, 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
[root@jboss02 ~]# 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
java
out-of-memory
Deepak Tewani
quelle
quelle
ExecutorService
stattdessen einen Thread-Pool ( ).Antworten:
Dies ist kein Speicherproblem, obwohl der Ausnahmenname dies stark nahelegt, sondern ein Problem mit den Betriebssystemressourcen. Ihnen gehen die nativen Threads aus, dh wie viele Threads das Betriebssystem Ihrer JVM erlauben wird.
Dies ist ein ungewöhnliches Problem, da Sie selten so viele benötigen. Haben Sie viel bedingungsloses Fadenlaichen, wo die Fäden sollten, aber nicht enden?
Sie können in Betracht ziehen, Callable / Runnables unter der Kontrolle eines Executors zu verwenden, wenn dies überhaupt möglich ist. Es gibt viele Standard-Executoren mit unterschiedlichem Verhalten, 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.)
quelle
Beim Auslastungstest ist dasselbe Problem aufgetreten. Der Grund dafür ist, dass JVM keinen neuen Java-Thread erstellen kann. Unten finden Sie den JVM-Quellcode
In meinem Fall erstellt Jboss zu viele Threads, um die Anforderung zu bedienen, aber alle Threads sind blockiert. Aus diesem Grund ist JVM sowohl mit Threads als auch mit Speicher erschöpft (jeder Thread enthält Speicher, der nicht freigegeben wird, da jeder Thread blockiert ist).
Bei der Analyse der Java-Thread-Dumps wurden fast 61.000 Threads durch eine unserer Methoden blockiert, was dieses Problem verursacht. Unten ist der Teil des Thread-Dumps
quelle
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 Limit erreichen. Besonders wenn es sich um eine so runde Zahl wie 32k handelt, ist ein Limit der einen oder anderen Art ein sehr wahrscheinlicher Schuldiger.
Sind Sie sicher, dass Sie wirklich 32k-Threads benötigen? Die meisten modernen Sprachen unterstützen Pools wiederverwendbarer Threads - ich bin sicher, Java hat auch etwas vorhanden (wie der
ExecutorService
Benutzer Jesper erwähnt hat). Vielleicht könnten Sie Threads aus einem solchen Pool anfordern, anstatt manuell neue zu erstellen.quelle
Ich würde empfehlen, auch die Thread-Stapelgröße zu überprüfen und zu prüfen, ob weitere Threads erstellt werden. Die Standardgröße für den Thread-Stapel für JRockit 1.5 / 1.6 beträgt 1 MB für 64-Bit-VMs unter Linux. 32K-Threads benötigen eine erhebliche Menge an physischem und virtuellem Speicher, um diese Anforderung zu erfüllen.
Versuchen Sie, die Stapelgröß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 außerdem, die horizontale Skalierung zu untersuchen, z. B. die Aufteilung Ihrer Anwendungsverarbeitung auf mehrere physische oder virtuelle Maschinen.
Bei Verwendung einer 64-Bit-VM hängt das tatsächliche Limit von der Verfügbarkeit des physischen und virtuellen Speichers des Betriebssystems und von Betriebssystemoptimierungsparametern wie ulimitc ab. Ich empfehle auch den folgenden Artikel als Referenz:
OutOfMemoryError: Neuer nativer Thread kann nicht erstellt werden - Problem entmystifiziert
quelle
Wenn jvm über systemd gestartet wird, gibt es in einigen Linux-Betriebssystemen möglicherweise eine maximale Anzahl von Aufgaben pro Prozess (Aufgaben 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 = unendlich
quelle
Ich hatte das gleiche Problem aufgrund von Geisterprozessen, die bei der Verwendung von top in bash nicht angezeigt wurden. Dies verhinderte, dass die JVM mehr Threads erzeugt.
Für mich wurde es aufgelöst, als alle Java-Prozesse mit jps aufgelistet wurden (einfach
jps
in Ihrer Shell ausführen ) und separat mit demkill -9 pid
Befehl bash für jeden Ghost-Prozess beendet wurden.Dies kann in einigen Szenarien hilfreich sein.
quelle
Sie haben die Möglichkeit, sich dem
java.lang.OutOfMemoryError: Unable to create new native thread
Problem zu stellen, wenn die JVM vom Betriebssystem nach einem neuen Thread fragt. Immer wenn das zugrunde liegende Betriebssystem keinen neuen nativen Thread zuweisen kann, wird dieser OutOfMemoryError ausgelöst. Das genaue Limit für native Threads ist sehr plattformabhängig. Es wird daher empfohlen, diese Limits durch Ausführen eines Tests zu ermitteln, der dem folgenden Linkbeispiel ähnelt. Im Allgemeinenjava.lang.OutOfMemoryError: Unable to create new native thread
durchläuft die verursachende Situation jedoch die folgenden Phasen:Referenz: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread
quelle
Um herauszufinden, welche Prozesse Threads erstellen, versuchen Sie:
Normalerweise leite ich die Ausgabe in eine Datei um und analysiere die Datei offline (die Anzahl der Threads für jeden Prozess ist wie erwartet oder nicht).
quelle
Wenn Ihr Job aufgrund von OutOfMemmory auf Knoten fehlschlägt, können Sie die Anzahl der maximalen Maps und Reduzierer überprüfen und die JVM für jeden auswählen. mapred.child.java.opts (der Standardwert ist 200Xmx) muss normalerweise basierend auf der spezifischen Hardware Ihrer Datenknoten erhöht werden.
Dieser Link könnte hilfreich sein ... bitte überprüfen
quelle
Ihre JBoss-Konfiguration weist einige Probleme auf. /opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m Xms und Xmx beschränken Ihre JBoss-Speichernutzung auf den konfigurierten Wert, sodass der Server ab 8 GB nur 512 MB verwendet + etwas mehr für seinen eigenen Zweck, erhöhen Sie diese Zahl, denken Sie daran, etwas für das Betriebssystem und andere Dinge, die dort laufen, frei zu lassen, und möglicherweise bringen Sie es trotz des unappetitlichen Codes zum Laufen. Das Reparieren des Codes wäre auch schön, wenn Sie können.
quelle
Dieser Fehler kann aus folgenden zwei Gründen auftreten:
Im Speicher ist kein Platz für neue Threads.
Die Anzahl der Threads überschreitet das Betriebssystemlimit.
Ich bezweifle, dass die Anzahl der Threads das Limit für den Java-Prozess überschritten hat
Möglicherweise liegt das Problem also am Gedächtnis. Ein zu berücksichtigender Punkt ist
Mögliche Lösung besteht darin, den Heapspeicher zu reduzieren oder die Gesamtgröße des RAM zu erhöhen
quelle
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.
Im Grunde habe ich so etwas gemacht wie:
wann ich das hätte tun sollen:
quelle
Zuallererst würde ich nicht so sehr das Betriebssystem / die VM beschuldigen, sondern den Entwickler, der den Code geschrieben hat, der sooo viele Threads erstellt . Grundsätzlich werden irgendwo in Ihrem Code (oder in einem Drittanbieter) viele Threads ohne Kontrolle erstellt .
Überprüfen Sie die Stacktraces / den Code sorgfältig und steuern Sie die Anzahl der erstellten Threads. Normalerweise sollte Ihre App nicht viele Threads benötigen, wenn dies der Fall ist, handelt es sich um ein anderes Problem.
quelle