Java Garbage Collection Guide

Efficient garbage collection keeps latency predictable and throughput high for JVM services. Understanding collector trade-offs helps you select the right strategy for your workload.

Collector Options

  • Serial GC: Single-threaded, suited for small heaps and embedded applications.
  • Parallel GC: Throughput-oriented; uses multiple threads to collect young and old generations.
  • CMS (Concurrent Mark-Sweep): Low-pause collector deprecated in Java 14; still present in legacy stacks.
  • G1 GC: Default in modern Java; balances pause times with region-based collection.
  • ZGC / Shenandoah: Ultra-low pause collectors for large heaps (tens to hundreds of GB).

Reading GC Logs

Enable detailed logging to analyse pause behaviour:

java -Xlog:gc*:file=gc.log:tags,uptime,time,level

Review metrics such as pause duration, promotion rates, and heap occupancy to identify tuning opportunities. Tools like GC Easy or JDK Mission Control simplify analysis.

Tuning Best Practices

  1. Choose the Right Collector: Match collector characteristics to latency/throughput goals.
  2. Size the Heap: Provide enough headroom to avoid consecutive full GCs; monitor Old Gen occupancy after each cycle.
  3. Profile Allocations: Use Flight Recorder or async-profiler to find allocation hotspots before adjusting GC flags.
  4. Test Under Load: Validate tuning changes with production-like traffic; GC settings often behave differently at scale.

Further Reading