2015-06-12 10 views
7

Ich verwende G1GC, jdk 1,7G1 junge GC nicht freien Speicher - zu Raum erschöpft

Java HotSpot(TM) 64-Bit Server VM (24.79-b02) for linux-amd64 JRE (1.7.0_79-b15), built on Apr 10 2015 11:34:48 by "java_re" with gcc 4.3.0 20080428 (Red Hat 4.3.0-8) 
Memory: 4k page, physical 32826020k(12590436k free), swap 33431548k(33358800k free) 

CommandLine flags: -XX:AutoBoxCacheMax=3000000 -XX:+DisableExplicitGC 
-XX:G1NewSizePercent=20 -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=10737418240 
-XX:InitiatingHeapOccupancyPercent=70 -XX:MaxDirectMemorySize=1073741824 -XX:MaxGCPauseMillis=1000 
-XX:MaxHeapSize=10737418240 
-XX:-OmitStackTraceInFastThrow -XX:+PrintGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps -XX:+UnlockExperimentalVMOptions 
-XX:+UseCompressedOops -XX:+UseG1GC 

Meist kleinere GC funktioniert gut, aber es immer noch ungewöhnlich fullGC beginnen, etwa ein bis zwei Mal in einem Stunde.

Dies ist ein normaler Fall junge GC log

3443.100: [GC pause (young), 0.3021260 secs] 
    [Parallel Time: 277.6 ms, GC Workers: 4] 
    [GC Worker Start (ms): Min: 3443100.5, Avg: 3443100.6, Max: 3443100.6, Diff: 0.1] 
    [Ext Root Scanning (ms): Min: 2.9, Avg: 3.0, Max: 3.1, Diff: 0.2, Sum: 11.9] 
    [Update RS (ms): Min: 33.5, Avg: 33.6, Max: 33.9, Diff: 0.4, Sum: 134.5] 
    [Processed Buffers: Min: 180, Avg: 204.8, Max: 227, Diff: 47, Sum: 819] 
    [Scan RS (ms): Min: 76.0, Avg: 76.2, Max: 76.3, Diff: 0.3, Sum: 304.9] 
    [Code Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.3] 
    [Object Copy (ms): Min: 164.4, Avg: 164.4, Max: 164.5, Diff: 0.1, Sum: 657.7] 
    [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] 
    [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.0, Sum: 0.2] 
    [GC Worker Total (ms): Min: 277.3, Avg: 277.4, Max: 277.4, Diff: 0.1, Sum: 1109.5] 
    [GC Worker End (ms): Min: 3443377.9, Avg: 3443378.0, Max: 3443378.0, Diff: 0.0] 
    [Code Root Fixup: 0.2 ms] 
    [Code Root Migration: 0.3 ms] 
    [Clear CT: 2.0 ms] 
    [Other: 22.1 ms] 
    [Choose CSet: 0.0 ms] 
    [Ref Proc: 15.7 ms] 
    [Ref Enq: 0.5 ms] 
    [Free CSet: 3.2 ms] 
    [Eden: 5996.0M(5996.0M)->0.0B(5648.0M) Survivors: 148.0M->196.0M Heap: 8934.5M(10.0G)->2997.2M(10.0G)] 
    [Times: user=1.13 sys=0.00, real=0.30 secs] 

Und das ist eine ungewöhnliche GC log vor dem fullGC. Es wiederholte sich zwei vor drei Mal, und es hat keine Speicher gelöscht.

3482.422: [GC pause (young) (to-space exhausted), 3.4878580 secs] 
[Parallel Time: 1640.5 ms, GC Workers: 4] 
    [GC Worker Start (ms): Min: 3482421.8, Avg: 3482422.4, Max: 3482424.0, Diff: 2.2] 
    [Ext Root Scanning (ms): Min: 2.1, Avg: 3.2, Max: 3.8, Diff: 1.7, Sum: 12.6] 
    [Update RS (ms): Min: 104.8, Avg: 105.2, Max: 105.6, Diff: 0.8, Sum: 421.0] 
    [Processed Buffers: Min: 201, Avg: 221.2, Max: 236, Diff: 35, Sum: 885] 
    [Scan RS (ms): Min: 75.1, Avg: 75.2, Max: 75.3, Diff: 0.1, Sum: 300.8] 
    [Code Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.2] 
    [Object Copy (ms): Min: 1455.9, Avg: 1456.1, Max: 1456.2, Diff: 0.3, Sum: 5824.2] 
    [Termination (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 0.4] 
    [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1] 
    [GC Worker Total (ms): Min: 1638.2, Avg: 1639.8, Max: 1640.4, Diff: 2.2, Sum: 6559.3] 
    [GC Worker End (ms): Min: 3484062.2, Avg: 3484062.2, Max: 3484062.2, Diff: 0.0] 
[Code Root Fixup: 0.2 ms] 
[Code Root Migration: 0.5 ms] 
[Clear CT: 2.0 ms] 
[Other: 1844.7 ms] 
    [Choose CSet: 0.0 ms] 
    [Ref Proc: 60.1 ms] 
    [Ref Enq: 0.5 ms] 
    [Free CSet: 1.2 ms] 
[Eden: 5648.0M(5648.0M)->0.0B(1876.0M) Survivors: 196.0M->172.0M Heap: 9441.9M(10.0G)->9352.3M(10.0G)] 
[Times: user=9.29 sys=0.05, real=3.49 secs] 

Dann begann er eine fullGC

3490.812: [Full GC 9626M->1879M(10G), 7.6059670 secs] 
[Eden: 0.0B(2048.0M)->0.0B(6144.0M) Survivors: 0.0B->0.0B Heap: 9626.3M(10.0G)->1879.5M(10.0G)], [Perm: 33901K->33901K(36864K)] 
[Times: user=10.24 sys=0.00, real=7.61 secs] 

Warum die letzte youngGC kein Gedächtnis reinigen haben?

+1

Ich weiß nicht, Details der JVM7 GC, aber im Allgemeinen eine junge Generation GC wird nicht sammeln, wenn es viele Hinweise von der älteren Generation in den jüngeren gibt, auch wenn diese Zeiger im alten Gen in Müll liegen . Es ist für einen Algorithmus unmöglich zu bestimmen, wann dies mit Sicherheit geschieht. Eine Möglichkeit ist es, zu beobachten, was in den Sammlungen junger Generationen wiedergefunden wird, und eine vollständige Sammlung auszulösen, wenn die Ergebnisse der jungen Gen-Sammlungen schlecht sind. Es ist wahrscheinlich, dass das hier passiert. Sobald der alte Müll befreit ist, können die Jungen folgen. – Gene

+1

einige Ihrer Parameter können G1 Heuristiken zu sehr einschränken. Sind Sie sicher, dass sie notwendig sind? Was sind deine Ziele, niedrige Pausenzeit oder hoher Durchsatz? Außerdem sollten Sie auf Java 8 aktualisieren. G1GC hatte immer noch viele Probleme unter Java 7. – the8472

Antwort

7

Sie leiden unter Evakuierungsfehlern, wie aus dem Teil to-space exhausted der Startnachricht für die Sammlung ersichtlich ist.

Dies tritt auf, wenn nicht genügend freier Speicherplatz auf Ihrem Heap vorhanden ist, um überlebende oder heraufgestufte Objekte (oder beides) zu promoten, und der Heap nicht mehr erweitert werden kann.

Monica Beckwith schreibt nach dem in Tips for Tuning the Garbage First Garbage Collector

Für G1 GC, ein Scheitern Evakuierung ist sehr teuer -

  • Für erfolgreich kopiert Objekte muss G1 die Referenzen und die Regionen aktualisieren festgenommen werden.
  • Für nicht erfolgreich kopierte Objekte wird G1 sie selbst weiterleiten und die Regionen an Ort und Stelle halten.

Oft G1 kann nicht mit dem Zuweisungsrate Schritt halten, wenn gezwungen, diese Operationen zu tun und wird schließlich zu einer vollständigen GC gezwungen wird aufgrund Zuordnungsfehler. Dies ist wahrscheinlich der Grund, warum Sie nach einigen Evakuierungsfehlern einen vollständigen GC sehen.

Monica Beckwith schreibt auch über mögliche Lösungen in Garbage First Garbage Collector Tuning

  • den Wert der -XX erhöhen: G1ReservePercent Option (und die Gesamt Haufen entsprechend) für die Menge an Reservespeicher zu erhöhen " zu-Raum ".

  • Den Markierzyklus früher starten, indem die -XX: InitiatingHeapOccupancyPercent reduziert wird.

  • Sie können auch den Wert der Option -XX: ConcGCThreads auf erhöhen, um die Anzahl der parallelen Markierungsfäden zu erhöhen.

Auch die Halde zu erhöhen, ist eine weitere Option, die die Wahrscheinlichkeit der Evakuierung Ausfälle reduzieren würde.

+0

Wenn wir den G1ReservePercent erhöhen, warum müssen wir auch den gesamten Heap erhöhen? Liegt es daran, dass der prozentuale Anstieg in absoluten Raum übersetzt werden muss? Es scheint etwas kontra intuitiv zu sein, weil es so aussieht, als ob G1Reserve-Speicherplatz absolut zunehmen würde, wenn nur der gesamte Heap erhöht würde. –

+1

@MoizRaja Wenn Sie den 'G1ReservePercent' erhöhen, ohne den Heapspeicher zu erhöhen, wird mehr Speicher in Reserve gehalten, und somit steht Ihrer Anwendung weniger Speicherplatz zur Verfügung als zuvor. Um dies zu kompensieren, muss der gesamte Heap erhöht werden. Sie haben Recht damit, dass die Erhöhung des gesamten Heaps auch die Reserve erhöht. Wenn Sie sowohl 'G1ReservePercent' als auch den Heap erhöhen, erhalten Sie von beiden Operationen einen erhöhten Speicherplatz. –

Verwandte Themen