2017-12-13 10 views
3

Ich habe drei Java 8 JVMs auf einer 64-Bit-Ubuntu-VM, die von einer minimalen Installation mit nichts außer den drei JVMs ausgeführt wurde. Die VM selbst hat 2 GB Arbeitsspeicher und jede JVM wurde von -Xmx512M begrenzt, was meiner Meinung nach in Ordnung wäre, da es ein paar hundert MB Speicherplatz geben würde. VorBegrenzung von Java 8 Speicherverbrauch

ein paar Wochen, ein abgestürzt und die hs_err_pid Dump zeigte:

# There is insufficient memory for the Java Runtime Environment to continue. 
# Native memory allocation (mmap) failed to map 196608 bytes for committing reserved memory. 
# 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. 

ich die JVM mit einer reduzierten Heap-Größe von 384 MB neu gestartet und bisher ist alles in Ordnung. Jedoch, wenn ich gegenwärtig auf der VM schauen Sie den Befehl ps verwenden und sortieren in RSS Größe absteigend Ich sehe

RSS %MEM VSZ PID CMD 
708768 35.4 2536124 29568 java -Xms64m -Xmx512m ... 
542776 27.1 2340996 12934 java -Xms64m -Xmx384m ... 
387336 19.3 2542336 6788 java -Xms64m -Xmx512m ... 
12128 0.6 288120 1239 /usr/lib/snapd/snapd 
4564 0.2 21476 27132 -bash 
3524 0.1 5724 1235 /sbin/iscsid 
3184 0.1 37928  1 /sbin/init 
3032 0.1 27772 28829 ps ax -o rss,pmem,vsz,pid,cmd --sort -rss 
3020 0.1 652988 1308 /usr/bin/lxcfs /var/lib/lxcfs/ 
2936 0.1 274596 1237 /usr/lib/accountsservice/accounts-daemon 
.. 
.. 

und der freie Befehl zeigt

   total  used  free  shared buff/cache available 
Mem:   1952  1657   80   20   213   41 
Swap:    0   0   0 

den ersten Prozess als Beispiel genommen wird, gibt es eine RSS-Größe von 708768 KB, obwohl das Heap-Limit 524288 KB (512 * 1024) wäre.

Ich bin mir bewusst, dass zusätzlicher Speicher über den JVM-Heap verwendet wird, aber die Frage ist, wie kann ich das kontrollieren, um sicherzustellen, dass ich nicht wieder den Arbeitsspeicher erschöpft? Ich versuche, die Größe des Heapspeichers für jede JVM so groß wie möglich zu setzen, ohne sie zu beschädigen.

Oder gibt es eine gute allgemeine Richtlinie, wie die Größe des JVM-Heapspeichers in Bezug auf die Gesamtspeicherverfügbarkeit festgelegt wird?

+0

Das Festlegen eines Limits verhindert nicht, dass eine JVM nicht mehr genügend Arbeitsspeicher hat. Wenn die Anwendungen diesen Speicher benötigen, ist alles, was Sie ändern werden, * welches * JVM nicht mehr genügend Arbeitsspeicher hat. – Holger

+0

Ich glaube nicht, dass die Anwendungen den Speicher "brauchen".Die Java-Anwendung, die mit 512 MB abgestürzt ist, lief beim Neustart mit 384 MB einwandfrei. Es sieht so aus, als wäre es abgestürzt, weil es versucht hat, Speicher innerhalb seiner 512 MB Grenze zu reservieren, aber dieser Speicher war nicht da (und es war nicht da, weil eine oder beide der anderen JVMs weit über 512 MB verwendeten). Durch das Reduzieren von Heap auf 384 MB kann der Garbage Collector (und der Prozessor) aktiver sein, aber es sucht nicht nach Speicher, der nicht vorhanden ist. – paulh

+1

Einstellung -Xmx hat nur die Kontrolle über den JVM-Heap, aber Sie haben keinen nativen Speicher mehr, wenn ein Fehler angezeigt wird. Bitte lesen Sie mehr über native Speicher und Dinge, die Sie beachten sollten - https://www.ibm.com/developerworks/java/library/j-nativememory-linux/ – Fairoz

Antwort

0

Es scheint keine Möglichkeit zu geben, zu steuern, wie viel zusätzlichen Speicher die JVM über den Heapspeicher benötigt. Durch Überwachen der Anwendung über einen Zeitraum kann jedoch eine gute Schätzung dieses Betrags erhalten werden. Wenn der Gesamtverbrauch des Java-Prozesses höher als gewünscht ist, kann die Größe des Heapspeichers reduziert werden. Eine weitere Überwachung ist erforderlich, um festzustellen, ob dies die Leistung beeinträchtigt.

mit dem Beispiel fort oben und mit dem Befehl ps ax -o rss, pmem, VSZ, pid, cmd --sort -rss wir die Nutzung als von heute sehen, ist

RSS %MEM VSZ PID CMD 
704144 35.2 2536124 29568 java -Xms64m -Xmx512m ... 
429504 21.4 2340996 12934 java -Xms64m -Xmx384m ... 
367732 18.3 2542336 6788 java -Xms64m -Xmx512m ... 
13872 0.6 288120 1239 /usr/lib/snapd/snapd 
.. 
.. 

Diese Java-Prozesse alle laufen auf der gleichen Anwendung, aber mit unterschiedlichen Datensätzen. Der erste Prozess (29568) ist stabil geblieben, wobei ungefähr 190 M jenseits des Heap-Limits verwendet wurden, während der zweite (12934) von 156 M auf 35 M reduziert wurde. Die gesamte Speicherbelegung des dritten Speichers ist deutlich unter der Größe des Heapspeichers geblieben, was darauf hindeutet, dass das Heap-Limit reduziert werden könnte.

Es würde scheinen, dass das Erlauben von 200MB Extra-Nicht-Heap-Speicher pro Java-Prozess hier mehr als genug wäre, da dies 600MB Spielraum insgesamt ergibt. Wenn Sie dies von 2 GB abziehen, bleiben 1400 MB übrig, so dass die drei -XMX kombinierten Parameterwerte unter diesem Wert liegen sollten.

Wie aus dem Lesen des Artikels in einem Kommentar von Fairoz zu lesen ist, gibt es viele verschiedene Möglichkeiten, wie die JVM nicht-Heap-Speicher verwenden kann. Eine davon, die messbar ist, ist die Thread-Stack-Größe. Der Standard für eine JVM kann unter Linux mit java -XX: + PrintFlagsFinal -version | gefunden werden grep ThreadStackSize Im obigen Fall ist es 1MB und da es ungefähr 25 Threads gibt, können wir sicher sagen, dass mindestens 25MB extra immer benötigt werden.