Java `OutOfMemoryError` beim erstellen < 100 threads
Die ich gelesen habe und die Tests und schlug meinen Kopf an der Wand für mehr als einen Tag, weil dieser Fehler.
Ich habe einige Java-code in eine Klasse namens Listener
sieht wie folgt aus
ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
boolean listening = true;
int count = 0;
while (listening) {
Runnable worker;
try {
worker = new ServerThread(serverSocket.accept()); //this is line 254
executor.execute(worker);
count++;
logger.info("{} threads started", count);
} catch (Exception e1){
//...
}
}
Ich habe das optimieren der JVM-Einstellungen -Xmx
(überall von 1 bis 15G) und -Xss
(überall von 104k 512M). Der server hat 24 GB RAM, sondern muss auch die Datenbank, die unterstützt das Programm.
Nach 2-20 threads erstellt werden (ein paar Dutzend existieren an anderer Stelle im Programm), bekomme ich die Fehlermeldung
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:657)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:943)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1325)
at xxx.Listener.run(Listener.java:254)
$java -version
ergibt:
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.1) (fedora-65.1.11.1.fc16-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
Es ist immer eine große Menge des freien Speichers auf dem system, wenn dies geschieht, und andere Programme weiterhin ausführen, in Ordnung. Was Java zu glauben, es hat nicht mehr Speicher für neue threads?
UPDATE:
Vielleicht ist größer, als ich dachte - ich bekam diese Fehlermeldung (nur einmal), wenn ich ^C
:
OpenJDK 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated
und das gleiche passiert, wenn ich versuchte, Sie zu töten, der client (ebenfalls in Java geschrieben und läuft auf dem gleichen server, es ist ein einzelner thread, der liest eine Datei und sendet Sie an den server über den socket), so dass es definitiv eine Grenze, jenseits der JVM verursacht einen zu stören die anderen, aber ich kann mir nicht vorstellen, was passiert, wenn ich noch Speicher frei und bin nicht mit swap? Server -Xmx1G -Xss104k Client -Xmx10M
UPDATE2:
Die Aufgabe des perl - Forks::Super
Bibliothek und den Betrieb der clients von bash let me get bis zu 34 threads, bevor der server abgestürzt mit OOME, so laufen mehrere clients auf jeden Fall hatte Sie eine Auswirkung auf die server, aber zur gleichen Zeit, ich sollte noch in der Lage sein, mehr als 34 (68 zählt man die clients) java-threads gleichzeitig. Die system-Ressourcen blockieren, die Schaffung von mehr threads (d.h. wo sollte ich schauen, um herauszufinden, den hog)? Wenn alles (clients, server, GC,...) läuft der Speicher in der gleichen Zeit, top
sagt diese über meine CPU-und Speicher-Auslastung:
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 24681040k total, 1029420k used, 23651620k free, 30648k buffers
Swap: 26836988k total, 0k used, 26836988k free, 453620k cached
UPDATE3: Hat die hs_error log unten zeigen, dass mein java nicht die 64 bit?
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources.
# Possible reasons:
# The system is out of physical RAM or swap space
# In 32 bit mode, the process size limit was hit
# Possible solutions:
# Reduce memory load on the system
# Increase physical memory or swap space
# Check if swap backing store is full
# Use 64 bit Java on a 64 bit OS
# Decrease Java heap size (-Xmx/-Xms)
# Decrease number of Java threads
# Decrease Java thread stack sizes (-Xss)
# Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.
#
# JRE version: 6.0_24-b24
# Java VM: OpenJDK 64-Bit Server VM (20.0-b12 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea6 1.11.1
# Distribution: Fedora release 16 (Verne), package fedora-65.1.11.1.fc16-x86_64
Was gibt Ihnen
ulimit -u
? Es gibt dir die max user processes. vielleicht sind Sie begrenzt durch die.ulimit -u
gibt 1024 - das könnte tatsächlich das problem sein. Wie kann ich diese Einstellung ändern?Versuchen Sie dies : in
/etc/security/limits.conf
set user soft nproc [your_val]
und user hard nproc [your_val]
. Sie können hinzufügen, einige andere config, wenn es nicht genug ist, finden Sie unter diesem link directory.fedoraproject.org/wiki/Performance_TuningFür Leute, die dies Lesen in der Zukunft, bitte beachten Sie in diesem bug-report in fedora und centos, die erklärt, die Grenzen der Bearbeitung
/etc/security/limits.conf
link @alain.janinm : diese Lösung zu ändern, nproc-Werte hast, mein problem zu lösen. Danke.InformationsquelleAutor kaz | 2012-05-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie begrenzen, indem
max user processes
ist, zu wissen, Ihre Grenzen zu verwenden :Limit ändern :
In
/etc/security/limits.conf
set :Können Sie hinzufügen, einige andere config, wenn es nicht genug, finden Sie diese link.
Hinweis : Die OP fand diese Fehlerbericht in fedora und centos, die erklärt, die Grenzen der Bearbeitung
/etc/security/limits.conf
.InformationsquelleAutor alain.janinm
Dein problem ist vermutlich im Zusammenhang mit JVM nicht zuordnen stack-Speicher für neue threads. Ironischerweise, dieses problem kann gelöst werden, durch die Senkung der heap-space (-Xmx) und stack-Speicher (-Xss). Überprüfen Sie hier, zum Beispiel, für eine gute Erklärung: http://www.blogsoncloud.com/jsp/techSols/java-lang-OutOfMemoryError-unable-to-create-new-native-thread.jsp
-Xmx1G -Xss104k
ich war in der Lage zu erstellen 6 threads (für insgesamt weniger als 40 explizit angelegt werden in meinem Programm). 104k ist das minimum-Xss-Wert auf meinem system, und 1G ist bei weitem nicht so groß wie es sein muss in der Produktion. Mittlerweile gibt es noch eine riesige Menge (über 8GB) kostenlos auf das system, wenn es läuft out of memory.104k ist ein seltsamer Wert 🙂 diese doc erzählen minimum 64 Kb oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom
Schon seltsam, aber wenn ich starte die JVM mit weniger als 104 wirft er diese Meldung und stürzt ab:
The stack size specified is too small, Specify at least 104k Could not create the Java virtual machine.
InformationsquelleAutor Hakan Serce
Es ist nicht der fehlende Speicher für Ihre neue threads, es fehlt die tatsächliche threads.
Das system ist wahrscheinlich hindert Sie daran: es gibt ein limit, die Anzahl der thread, die ein Nutzer erstellen kann. Sie können Abfrage:
Beachten Sie, dass Sie vielleicht beeinflusst von anderen Prozessen auf dem gleichen Computer, Sie werden Sie viele thread zu.
Vielleicht finden Sie diese Frage hilfreich:
Maximale Anzahl von threads pro Prozess in Linux?
$ cat /proc/sys/kernel/threads-max
gibt 385345 - auf einem server mit meinem Programm ein paar ssh/bash-shells, und MySQL, ich glaube nicht, ich bin schlagen, begrenzen. Auch einige besonders schreckliche jvm-Einstellungen dazu führen, dass es zu sterben, nach weniger threads erstellt wurden, als andere, was darauf schließen lässt, dass es eine JVM Problem.InformationsquelleAutor Daniel Teply
Nur zur Klarstellung:
Geben Sie einen
ServerSocket
zu denThread
. Senden Sie Daten an diesem Socket? Vielleicht Sie speichern zu viele Daten in den Thread-Kontext. Tak einen Blick für ein Muster, wo Sie speichern Streamdata in einembyte[]
.Socket
auf das GewindeServerSocket.accept()
gibt eineSocket
Objekt. Und ja, ich übergebe Daten aus einem anderen Programm und lese -, Daten -, Prozess -, und dann trennen Sie. In der test-version, die im thread akzeptiert die Steckdose, wartet, dann schließt es und stirbt. Die Buchse bekommt, Lesen sich wie ein stream, also denke ich nicht, dass ich mich übergeben den gesamten Inhalt des Streams an den thread. Außerdem, bis sich der client authentifiziert, es werden keine Daten gesendet, um die stream-Puffer wird nur ein paar hundert bytes.InformationsquelleAutor Christian Kuetbach