Saltar a contenido

Week 10 - The Generational Hypothesis and the Modern GCs

Conceptual Core

"Most objects die young." This is the weak generational hypothesis, and it is what every modern GC except non-generational ZGC (deprecated as default in 23+) and Epsilon is built on. You need to know the family tree: Serial → Parallel → CMS (removed) → G1 → ZGC → Shenandoah → Generational ZGC.

Mechanical Detail

  • Serial GC (-XX:+UseSerialGC) - single-threaded; only for tiny heaps / containers. Default in some container configs.
  • Parallel GC (-XX:+UseParallelGC) - throughput-optimized, stop-the-world. Default before 9.
  • G1 GC (-XX:+UseG1GC, default since 9) - region-based, mostly-concurrent, predictable pause-time goal (-XX:MaxGCPauseMillis=200 default). The general-purpose default.
  • ZGC (-XX:+UseZGC) - concurrent, region-based, colored pointers, sub-millisecond pauses. Generational ZGC (JEP 439, GA in 21) is the modern form; on 23+ it's the default flavor of -XX:+UseZGC. Use for latency-sensitive services with multi-GB heaps.
  • Shenandoah (Red Hat, -XX:+UseShenandoahGC) - concurrent compaction via Brooks pointers / load-reference barriers. Comparable use case to ZGC.
  • Epsilon (-XX:+UseEpsilonGC) - no-op collector. For short-lived batch jobs or GC-perf testing.
  • Picking: G1 by default; ZGC for latency-sensitive ≥4GB heaps; Parallel for throughput-only batch; Serial for tiny containers; Shenandoah if your stack is RHEL-flavored and you've measured it wins.

Lab

Take a sample allocation-heavy app (a small JSON parser benchmark works). Run it under all four major GCs with identical heap. Collect logs with -Xlog:gc*=info:file=gc.log:time,uptime. Plot pause times.

Idiomatic Drill

Read JEPs 439 (Generational ZGC) and 248 (Make G1 the Default).

Production Hardening Slice

Add a GC-log parser to your hardening/ template (or wire up gceasy.io / GCViewer). One command from gc.log to a chart.

Comments