Ich habe gelesen und getestet und schlug meinen Kopf an der Wand für mehr als einen Tag wegen dieses Fehlers.Java "OutOfMemoryError" beim Erstellen von <100 Threads
Ich habe einige Java-Code in einer Klasse namens Listener
die
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 die JVM-Einstellungen -Xmx
Tweaking wurden (überall von 1 bis 15 g) (von 104k bis 512M überall) und -Xss
wie diese aussieht. Der Server verfügt über 24 GB RAM, muss aber auch die Datenbank ausführen, die das Programm unterstützt.
Nach 2-20 Fäden erstellt werden (ein paar Dutzend existieren an anderer Stelle im Programm als auch), erhalte ich die Fehler
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 In diesem Fall ist der freie Speicher auf dem System frei und andere Programme werden weiterhin ordnungsgemäß ausgeführt. Was verursacht Java, dass es keinen Speicher mehr für neue Threads hat?
UPDATE: Vielleicht ist größer, als ich dachte- ich es geschafft, diesen Fehler zu bekommen (nur einmal), wenn ich ^C
verwendet:
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, das zu töten Client (auch in Java und läuft auf dem gleichen Server geschrieben, ist es ein einzelner Thread, der eine Datei liest und sendet sie an den Server über die Socket), so gibt es auf jeden Fall eine Grenze, jenseits der JVM eine mit dem anderen zu stören verursacht, aber ich kann mir nicht vorstellen, was passiert, wenn ich noch freie Speicher habe und keinen Swap benutze? Server -Xmx1G -Xss104k Client--Xmx10M
UPDATE2: Aufgeben der Perl-Bibliothek Forks::Super
und laufen die Kunden von bash lassen Sie mich zu 34 Threads aufstehen, bevor der Server mit OOME abgestürzt, so dass mehrere Clients laufen auf jeden Fall einen Einfluss hatte auf dem Server, aber zur gleichen Zeit soll ich noch in der Lage sein, mehr als 34 laufen Java-Threads zu einem Zeitpunkt (68, wenn einer der Clients zählt). Welche Systemressourcen blockieren die Erstellung von mehr Threads (d. H. Wo soll ich suchen, um das Schwein zu finden)? Wenn alles (Clients, Server, GC ...) läuft zur gleichen Zeit der Erinnerung heraus, sagt top
dies über meine CPU- und Speichernutzung:
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: Ist das hs_error log unten zeigen, dass meine Java ist nicht 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
Ist die ServerThread-Instanz von java.lang.Thread? Dann sollte es mit Thread.start() gestartet werden, und Thread-Pool ist nicht sinnvoll. Wenn nicht, wie werden Sie Socket-Verbindung mit einem einfachen Runnable dienen? Es ist knifflig, da Tasks, die von einem Threadpool gesteuert werden, nicht auf Eingaben warten können oder Threads (Deadlock) auftreten können. –
ServerThread ist eine schlecht benannte Klasse von mir selbst 'öffentliche Klasse ServerThread implementiert Runnable {... public void run() {...} ...}' Ich sehe Ihre Sorge, dass es möglicherweise schlecht warten würde Eingabe in einen Pool (es gibt eine Timeout-Funktion), aber ich möchte nicht jedes Mal, wenn ein Client eine Verbindung herstellt, einen neuen Thread erstellen - das wäre ein enormer Overhead für relativ kurze Interaktionen und würde trotzdem meine Thread-Erstellungsprobleme nicht lösen. – kaz
Haben Sie getestet, wie viele Threads Sie in einer einfacheren Anwendung erstellen können? – Jivings