Ich habe eine Web-App, die auf Tomcat ausgeführt wird, die Max Heap-Größe auf 8 GB festgelegt hat.Was bewirkt, dass ein vollständiger GC ausgeführt wird?
Folgende sind meine vm args.
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m -Xmx8192m -XX:+UseConcMarkSweepGC"
Wenn keine Benutzer in der App einloggen, nicht reinigbar Speicher (die nach einer Garbage Collection befindet) ist sehr gering (etwa 1 GB).
In dieser Situation, wenn ich das Speicherwachstum Muster mit jconsole beobachten, sehe ich eine konstante Speichererweiterung für ca. 4 GB und dann Garbage Collector läuft und Speicher wieder auf etwa 1 GB fällt. Dieses Muster wird fortgesetzt, wenn kein Benutzer angemeldet wird.
Wenn ich die GC-Daten protokolliere, beobachte ich etwas wie unten.
2017-02-14T15:30:44.553+0530: 591.922: [GC (Allocation Failure) [PSYoungGen: 1501051K->631966K(1833472K)] 2392189K->1523112K(3030016K), 1.5100144 secs] [Times: user=1.49 sys=0.01, real=1.51 secs]
2017-02-14T15:31:20.335+0530: 627.705: [GC (Allocation Failure) [PSYoungGen: 1553054K->595007K(1842176K)] 2444200K->1570521K(3038720K), 1.3050284 secs] [Times: user=1.27 sys=0.04, real=1.31 secs]
2017-02-14T15:33:33.682+0530: 761.052: [GC (Allocation Failure) [PSYoungGen: 1516095K->556800K(1842176K)] 2491609K->1596474K(3038720K), 1.6957154 secs] [Times: user=1.67 sys=0.03, real=1.69 secs]
2017-02-14T15:33:35.378+0530: 762.748: [Full GC (Ergonomics) [PSYoungGen: 556800K->365446K(1842176K)] [ParOldGen: 1039673K->1196476K(2018304K)] 1596474K->1561923K(3860480K), [Metaspace: 70472K->70472K(1114112K)], 11.2779843 secs] [Times: user=11.13 sys=0.09, real=11.28 secs]
2017-02-14T15:34:56.232+0530: 843.602: [GC (Allocation Failure) [PSYoungGen: 1286534K->216613K(1842176K)] 2483011K->1609875K(3860480K), 1.4938761 secs] [Times: user=1.45 sys=0.05, real=1.50 secs]
Wie es zu sehen ist, manchmal ein Voll GC durchgeführt wird, die eine beträchtliche Menge an Zeit (11 Sekunden) im Vergleich zu kleineren GC (ca. 1 Sekunde) stattgefunden hat.
Da alle anderen Threads während GC angehalten werden, reagiert der Server nicht, wenn ein Benutzer versucht, während eines vollständigen GC auf die Webanwendung zuzugreifen.
Was ich wissen wollte ist, was löst diesen Full GC aus? Gemäß dem Protokoll sind geringfügige GC-Ereignisse aufgrund von Zuweisungsfehlern und Full GC ist auf Ergonomics
zurückzuführen. Was bedeutet das?
Kann ich in diesem Fall verhindern, dass Full GC auftritt? Es gibt genügend freien Heap-Speicherplatz übrig, und ich möchte Full GC verzögern, bis keine signifikante Speicherreduktion aufgrund von untergeordneten GC auftritt.
Könnten Sie bitte alle GC-relevanten VM-Optionen hinzufügen, die Sie verwenden (Xms, MaxGCPauseMillis, welche Kollektoren, ...) plus den physischen Speicher Ihres Servers. Wenn Sie niedrige Pausenzeiten wünschen, ist das Verzögern der vollen GCs nicht der Weg zu gehen, da die Pausen weniger, aber länger sind. So scheint es, dass Ihr Heap zu groß für die Ziele konfiguriert ist, die Sie erreichen wollen (und Sie verwenden den falschen Collection-Algorithmus). –
@ piet.t, vm Optionen hinzugefügt –
in Frage zu stellen Es ist möglich, dass die Anwendung explizit tut 'System.gc()' ruft irgendwo im Code. Ich habe gesehen, dass der CMS-Sammler ein bisschen verrückt geworden ist und immer einen Stop-the-World-Full-GC nach einem Aufruf von 'System.gc()' ausführt. Sie können den GC dazu veranlassen, solche Aufrufe über die JVM-Option "-XX: + DisableExplicitGC" zu ignorieren. –