JVM Garbage Collector Evolution and Modern Selection Criteria

Garbage Collector Classification Framework

Garbage collection implementations vary across JVM vendors and versions, with numerous collectors developed through Java's evolution. Classification can occur along multiple dimensions:

Concurrency Models

  • Serial Collectors: Single-threaded operation (e.g., Serial GC). Efficient in constrained environments like client applications with small heaps due to minimal thread coordination overhead.
  • Parallel Collectors: Multi-threaded throughput optimization (e.g., Parallel GC). Maximizes CPU utilization for faster collection but employs stop-the-world pauses.
  • Concurrent Collectors: Overlap collection with application execution (e.g., G1, ZGC). Minimizes pause times through background processing, though some stop-the-world phases remain.

Memory Management Approaches

  • Compacting Collectors: Eliminate fragmentation via object relocation (e.g., Parallel Old using mark-compact).
  • Non-Compacting Collectors: Maintain free lists without relocation (e.g., CMS using mark-sweep).
  • Region-Based: Divide heap into fixed-size regions (e.g., G1's 1-32MB regions).

Performance Tradeoffs

Three critical metrics form an optimization triangle where improving one often degrades another:

Throughput vs. Latency

  • Throughput: Ratio of application execution time to total runtime (application + GC time). Optimized by reducing GC frequency through larger heaps or less aggressive collection.
  • Pause Time: Duration of stop-the-world interruptions. Minimized through concurrent processing and region-based collection.
  • Memory Footprint: Total heap consumption. Smaller heaps improve locality but increase GC frequency.

Modern applications increasingly prioritize pause time predictability, especially for interactive systems. The ideal collector balances these based on workload characteristics rather than maximizing any single metric.

Evolution of JVM Collectors

Historical Progression

  • Serial (JDK 1.3): Original single-threaded collector
  • Parallel (JDK 6): Throughput-focused multi-threaded collector
  • CMS (JDK 1.4.2): First concurrent collector (removed in JDK 15)
  • G1 (JDK 7u4): Region-based collector targeting predictable pauses
  • ZGC (JDK 11): Sub-10ms pauses for multi-terabyte heaps

Modern Collector Landscape

Collector Best For Key Characteristics
Parallel GC Batch processing Maximizes throughput via aggressive parallel collection
G1 GC General-purpose servers Predictable pauses through region-based collection
ZGC Low-latency systems Near-constant pause times regardless of heap size

G1 Collector Architecture

G1 revolutionized heap management by dividing memory into fixed-size regions (1-32MB), enabling selective collection of garbage-rich regions. Key innovations include:

Region Management

  • Regions dynamically switch between Eden, Survivor, and Old roles
  • Humongous regions handle objects >50% of region size
  • Remembered Sets track cross-region references without full scans

Collection Cycle

  1. Youth Collection: Stop-the-world evacuation of Eden/Survivor regions
  2. Concurrent Marking: Background liveness analysis triggered at 45% heap occupancy
  3. Mixed Collection: Evacuates both young and selected old regions based on garbage density

Example configuration for latency-sensitive applications:

// Target 100ms max pauses with 4GB heap
java -Xmx4g -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=100 \
     -XX:G1HeapRegionSize=4m \
     -XX:InitiatingHeapOccupancyPercent=35 \
     MyApp

Advanced Collectors

ZGC (JDK 11+)

ZGC achieves ultra-low pauses through:

  • Colored pointers for concurrent marking
  • Load barriers for heap access coordination
  • Multi-mapping of virtual memory spaces

Operates with consistent sub-10ms pauses regardless of heap size (tested up to 16TB). Enabled via:

java -XX:+UseZGC -Xmx16g MyApp

Shenandoah (OpenJDK 12+)

Similar goals to ZGC but uses Brooks pointers for concurrent compaction. Particularly effective for:

  • Applications with high allocation rates
  • Systems requiring consistent sub-50ms pauses

Collector Selection Strategy

Modern selection guidelines:

  • < 100MB heaps: Serial GC (low overhead)
  • Throughput-critical workloads: Parallel GC
  • General server applications: G1 GC (default since JDK 9)
  • Latency-sensitive systems: ZGC or Shenandoah

No universal solution exists—selection must align with specific application requirements and hardware constraints. Critical evaluation should include:

  • Pause time distribution (not just averages)
  • Memory footprint under sustained load
  • Throughput during peak operations

GC Log Analysis Essentials

Key diagnostic parameters:

java -Xlog:gc*:file=gc.log:time \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     MyApp

Interpreting mixed collection events:

[GC pause (G1 Evacuation Pause) (mixed)
 Ed: 120M(120M)->25M(120M) 
 Old: 800M(1000M)->750M(1000M)
 Total: 920M->775M(1120M),
 0.120 secs]

Indicates evacuation of young regions (Ed) and selected old regions (Old), with 120ms pause duration.

Practical Tuning Recommendations

  • Avoid explicit young generation sizing with G1/ZGC—let adaptive algorithms optimize
  • Set realistic pause targets (e.g., 200ms rather than 10ms) to maintain throughput
  • Monitor humongous object allocation patterns with G1
  • Use GC logs with tools like GCViewer for empirical analysis

Modern JVMs require less manual tuning than historical versions, but workload-specific validation remains essential.

Tags: GarbageCollection G1GC ZGC JVMTuning MemoryManagement

Posted on Fri, 24 Jul 2026 16:33:01 +0000 by lalabored