English
Enabling GC Logging
GC logging is cheap (typically < 3% overhead) and is your best friend when a production incident strikes. Enable it always, everywhere.
Java 9 and later (unified logging)
bash
java -Xlog:gc*:file=/var/log/myapp/gc.log:time,uptime,level,tags:filecount=5,filesize=20m -jar app.jar-Xlog:gc*— everything GC related, including heap sizes and pause phases (required for a complete EasyGC report).file=...— rotate instead of growing forever (filecount/filesize).time,uptime— wall-clock and JVM-uptime stamps on every line.
Minimum useful set
-Xlog:gc:file=gc.log already works, but -Xlog:gc* gives the full picture (region stats, metaspace, phase timings).
Java 8 and earlier
bash
java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime \
-Xloggc:/var/log/myapp/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 \
-XX:GCLogFileSize=20M -jar app.jar-XX:+PrintGCDetails— per-generation sizes (young/old/metaspace) — required for the memory breakdown.-XX:+PrintGCDateStamps— wall-clock timestamps for correlating with application logs.- On Java 8u92+ you can also add
-XX:+PrintGCTimeStampsfor uptime stamps.
What a good log looks like
Java 9+ (G1):
[2024-05-01T10:00:00.524+0000][0.524s][info][gc] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 412M->34M(1024M) 12.134msJava 8 (Parallel):
2024-05-01T10:00:01.234+0000: 1.234: [GC (Allocation Failure) [PSYoungGen: 262144K->32768K(305664K)] 262144K->49152K(1007616K), 0.0383211 secs] [Times: user=0.12 sys=0.03, real=0.04 secs]Both carry everything EasyGC needs: when the collection happened, why it was triggered, heap before → after, capacity and how long the JVM was stopped.
Container notes
- Write the log to a mounted volume, not the container filesystem.
- Remember that the JVM sees container memory limits — check
-XX:MaxRAMPercentagetoo.