Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Core Fundamentals

Object-Oriented Programming

  • Classes and Objects
  • Inheritance and Polymorphism
  • Interfaces and Abstract Classes

Collections Framework

  • List, Set, and Map
  • Generics
  • Collections Framework Recap
  • HashMap Deep Dive
  • TreeMap & LinkedHashMap
  • Iterators & Modification Semantics

Exceptions & Best Practices

  • Exception Handling
  • equals() and hashCode()
  • String Manipulation

JVM Internals & Memory Management

  • JVM Memory Areas
  • Garbage Collection Fundamentals
  • Modern Garbage Collectors
  • Memory Leaks in Java
  • GC Tuning & Diagnostics
Chaturmind
← Java Core Fundamentals

Object-Oriented Programming

  • Classes and Objects
  • Inheritance and Polymorphism
  • Interfaces and Abstract Classes

Collections Framework

  • List, Set, and Map
  • Generics
  • Collections Framework Recap
  • HashMap Deep Dive
  • TreeMap & LinkedHashMap
  • Iterators & Modification Semantics

Exceptions & Best Practices

  • Exception Handling
  • equals() and hashCode()
  • String Manipulation

JVM Internals & Memory Management

  • JVM Memory Areas
  • Garbage Collection Fundamentals
  • Modern Garbage Collectors
  • Memory Leaks in Java
  • GC Tuning & Diagnostics
HomeLearnJavaJava Core FundamentalsJVM Internals & Memory Management
✓ FreeAdvanced· 9 min read

Modern Garbage Collectors

Parallel GC, G1 (the default since Java 9), ZGC's sub-millisecond pauses via colored pointers, Shenandoah, and how to actually choose between them.

Published September 23, 2026


Modern Garbage Collectors

Garbage Collection Fundamentals covered the shared vocabulary (generations, mark-sweep-compact, GC roots). This lesson covers the actual collector implementations that ship with the JVM, each making a different tradeoff between throughput and pause time.

Parallel GC — throughput-oriented, stop-the-world

Uses multiple threads to perform a stop-the-world collection (all application threads paused during GC) as fast as possible. It doesn't try to minimize individual pause durations — it tries to maximize total application throughput (time spent doing useful work vs time spent in GC), accepting occasionally longer pauses in exchange for lower overall GC overhead. This makes it a good fit for batch jobs — a nightly ETL pipeline or a report generator that cares about total wall-clock completion time, not about any single pause being noticeable to an end user (because there is no end user waiting in real time).

G1GC — region-based, predictable pause-time goal, default since Java 9

G1 ("Garbage First") divides the heap into many equally-sized regions rather than a small number of large, contiguous generational spaces — each region can independently be Eden, Survivor, or Old, and this flexibility is what lets G1 pick which regions to collect based on which ones have the most garbage ("garbage first" — literally collecting the regions that will free the most memory for the least work).

  • Remembered sets: each region tracks references into it from other regions, so G1 can determine a region's live objects without having to scan the entire heap for incoming references every time — a critical optimization that makes partial-heap collection practical.
  • Mixed collections: a G1 collection can gather both young-gen regions and a subset of old-gen regions in the same pause, incrementally chipping away at old-gen garbage rather than requiring one giant Full GC.
  • -XX:MaxGCPauseMillis: G1's signature feature — you specify a target maximum pause time, and G1 adjusts how much work it attempts per collection cycle (how many regions to collect) to try to stay under that target. It's a soft goal, not a hard guarantee — an application generating garbage faster than G1 can keep up with can still exceed it.

ZGC — concurrent, sub-millisecond pauses, colored pointers

ZGC does almost all of its work concurrently with the running application — marking and relocating live objects while application threads keep executing, rather than stopping them. The mechanism that makes concurrent relocation (not just marking) safe is colored pointers: ZGC steals a few unused bits in every 64-bit object reference to encode metadata about that reference's state (has this object been relocated? does it need remarking?) directly in the pointer itself. When the application reads a pointer, a lightweight check (a "load barrier") inspects those color bits and, if the object has moved, transparently redirects to its new location — this is what lets ZGC move objects while the application is still running and potentially holding references to them, without a stop-the-world pause for the relocation itself. The result: pause times measured in single-digit milliseconds or less, largely independent of heap size (a multi-terabyte heap and a small heap have similarly low pause times).

Shenandoah — concurrent compaction, similar goals to ZGC

Developed separately (originally by Red Hat) but solving the same core problem: low-pause concurrent compaction. Shenandoah achieves concurrent compaction via a different mechanism than ZGC's colored pointers (a forwarding pointer stored directly in each object's header, read via a lightweight barrier on access) — different implementation technique, same fundamental goal of moving objects without a long stop-the-world pause.

Choosing a collector

WorkloadCollector
Throughput-sensitive batch job, no user waiting on individual latencyParallel GC
General-purpose service, want a tunable pause-time targetG1GC (the default — right for most services)
Latency-critical service, large heap, sub-millisecond pauses matterZGC or Shenandoah

The honest default answer for most Spring Boot services: G1 is already the default since Java 9 and is the right choice unless you have a specific, measured reason to reach for something else — ZGC/Shenandoah's concurrent-everything approach trades some CPU overhead (the load barriers on every reference read aren't free) for pause-time guarantees that most applications don't actually need.

Follow-up questions this topic invites — and their answers

Q: If ZGC has such low pause times, why isn't it the default over G1? A: The concurrent load-barrier mechanism has a real (if often small) CPU throughput cost paid on every reference access, and for applications where G1's pause times are already acceptable, that tradeoff isn't worth making — G1 remains the better general-purpose default; ZGC earns its cost specifically when pause time is the metric that matters most.

Q: How does G1's remembered-set mechanism avoid becoming its own overhead problem? A: Maintaining remembered sets isn't free — every cross-region reference write needs to update the target region's remembered set (via a write barrier) — but this cost is paid incrementally, spread across normal application execution, in exchange for avoiding a full-heap scan during every collection, which is the far larger cost it's designed to prevent.

Q: Can you switch collectors without recompiling the application? A: Yes — the collector is selected via a JVM startup flag (-XX:+UseG1GC, -XX:+UseZGC, -XX:+UseParallelGC, -XX:+UseShenandoahGC), entirely independent of application code; switching collectors to test a different tradeoff is a deployment/ops change, not a code change.

Q: Is a smaller heap always better for pause times, or does that only apply to some collectors? A: It mainly applies to traditional stop-the-world collectors like Parallel GC, where pause time scales with how much of the heap needs scanning — ZGC's pause times are specifically designed to stay low largely independent of heap size, which is one of its main selling points for very large heaps where a traditional collector's pauses would scale up proportionally.

Previous

Garbage Collection Fundamentals

Next

Memory Leaks in Java

AI Tutor

Lesson: Modern Garbage Collectors

Quick actions

AI responses can be inaccurate. Verify critical information.