Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering 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
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
Chaturmind
← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 8+ Years (Senior & Lead)JVM Internals & Performance
✓ FreeAdvanced· 12 min read

Garbage Collectors Deep Dive — Interview Questions

JVM memory regions, heap allocation (TLABs, bump-the-pointer, humongous/large objects), generational collection and minor vs major vs full GC, GC roots, every HotSpot collector (Serial, Parallel, CMS, G1, ZGC, Shenandoah, Epsilon) with the real default-collector history, how G1 works and differs from CMS and ZGC, stop-the-world pauses and their causes, frequent Full GCs, compaction and fragmentation, promotion and allocation failures, and distributed GC.

Published September 25, 2026


How to use this lesson

GC questions at this level are about choosing and diagnosing:

  • Which collector for which service level objective (SLO)?
  • Why do we see 2-second pauses?
  • Why is Full GC happening every minute?

Know the modern collectors (G1 by default, generational ZGC for low latency), and correct the outdated "CMS" answers.

Q1. What are the JVM's memory regions, and what goes where?

Short answer:

  • Heap (shared): all objects and arrays, including the Class mirrors (and their static fields) and interned strings. It's generational in most collectors: young (Eden + two Survivor spaces) and old. G1 and ZGC organise it as regions.
  • Metaspace (native): class metadata and method bytecode. Also the compressed class space.
  • Code cache (native): JIT-compiled code.
  • Per thread: the Java stack (frames with locals and operand stacks), the native method stack, and the program counter.
  • Other native memory: direct ByteBuffers and mapped files, GC structures (remembered sets, card tables, mark bitmaps), thread structures, symbol tables, and native libraries.

Learn it in depth → JVM Memory Areas

Q2. How is memory allocated on the heap, and is the heap size fixed?

Short answer: Allocation is very cheap:

  • Each thread allocates in its own TLAB inside Eden (see Q3), by bumping a pointer. That takes a few instructions, with no locking.
  • If the TLAB is full, the thread gets a new one. If Eden is full, a young GC runs.
  • Large objects may bypass Eden. In G1, objects of at least half a region are humongous, and are allocated directly in contiguous old-generation regions (DXB-613).

The heap size isn't fixed:

  • It starts at -Xms, and can grow up to -Xmx. The collectors resize it based on GC time and occupancy goals, and can shrink it too: G1 uncommits memory during idle periods (JEP 346), and ZGC uncommits too.
  • In containers, the JVM is container-aware (Java 10+). The default max heap is 25% of container memory, and you'd typically set -XX:MaxRAMPercentage=70-75.
  • For latency-sensitive services, many teams set -Xms = -Xmx, to avoid resize pauses, and with -XX:+AlwaysPreTouch, to pre-fault pages.

Q3. What is a TLAB, and how does it speed up allocation?

Short answer: A Thread-Local Allocation Buffer is a chunk of Eden reserved for one thread. Allocating an object is a pointer bump inside the thread's own TLAB, so there's no synchronisation with other threads. That's why new in Java is often faster than malloc.

  • When a TLAB fills up, the thread retires it (the remaining space is filled with a dummy object), and gets a new TLAB with one atomic operation.
  • An object too big for the TLAB is allocated directly in the shared Eden (slow path), or in a humongous region.
  • TLAB sizes adapt per thread, based on allocation rate.

Key points to cover:

  • TLABs don't change which objects survive. Promotion to the old generation depends on object age and survivor space, not on the TLAB.

Q4. What's the difference between minor, major and full GC?

Short answer:

  • Minor (young) GC: collects only the young generation. Live objects are copied from Eden and one Survivor space into the other Survivor space, or promoted to old. It's frequent, and usually short: the pause is proportional to the live objects, not the garbage.
  • Major GC: collects the old generation. The term is used loosely, and depends on the collector: CMS or G1 concurrent marking, or G1's mixed collections (young plus some old regions).
  • Full GC: collects the whole heap (and possibly Metaspace), usually stop-the-world and compacting. For G1 and the concurrent collectors, a Full GC is a fallback, and a sign of trouble.

Always read the GC log, rather than relying on these labels.

Q5. What are GC roots?

Short answer: The starting points of the reachability graph. Anything reachable from them is live. They include:

  • local variables and operand-stack references in active thread frames;
  • static fields (through loaded classes);
  • JNI references (global and local);
  • active thread objects themselves;
  • monitors held by threads;
  • classes loaded by the system loaders;
  • JVM-internal references (the string table, the code cache).

Memory-leak analysis is essentially: find the path from a GC root to the unexpectedly retained object.

Q6. Compare Serial, Parallel, CMS, G1, ZGC, Shenandoah (and Epsilon). When would you choose each?

Short answer:

CollectorDesignPausesBest for
Serial (-XX:+UseSerialGC)Single-threaded, generational, STWLong for big heapsSmall heaps, 1 CPU or tiny containers, CLI tools
Parallel (UseParallelGC)Multi-threaded, STW, compactingProportional to the heapThroughput: batch jobs, where pauses don't matter
CMSConcurrent old-gen mark-sweep, no compactionLow, but fragmentation, then a Full GCDeprecated in 9, removed in Java 14. Don't choose it
G1 (the default)Region-based, generational, concurrent marking, incremental compactionTarget (MaxGCPauseMillis=200), typically 10–200 msGeneral-purpose services, heaps from about 4 GB to many tens of GB
ZGC (UseZGC)Concurrent marking and relocation (coloured pointers, load barriers). Generational since Java 21, and the only mode since Java 24Sub-millisecond, independent of heap size (up to 16 TB)Low latency, and large heaps
Shenandoah (UseShenandoahGC)Concurrent compaction (Brooks pointers/LRB). Generational mode is a product in Java 25Low ms, independent of heap sizeLow latency (in OpenJDK builds from Red Hat, Amazon and others)
Epsilon (UseEpsilonGC)No-op: allocates, never collectsNone, until OOMPerformance testing, very short-lived jobs

Rule of thumb: keep G1, unless latency SLOs (p99.9 in single-digit milliseconds) require generational ZGC, or a pure batch workload wants Parallel.

Learn it in depth → Modern Garbage Collectors

Q7. Explain every garbage collector up to the latest Java release. (The CJ5 version)

Short answer: The table above covers them. The history is what interviewers probe:

  • Serial: the original collector.
  • Parallel: the throughput collector.
  • CMS (Java 1.4.1): the first mostly-concurrent collector. It was never compacting, and was removed in Java 14.
  • G1: production in Java 7u4, and the default since Java 9.
  • Epsilon: Java 11.
  • ZGC: experimental in 11, production in 15, generational in 21, and non-generational mode removed in 24.
  • Shenandoah: production in 15, with generational mode added later.

Each generation reduced pause times, by moving work (marking, then compaction) concurrent with the application, in exchange for barriers that cost some throughput.

Q8. What are the default garbage collectors in different Java versions?

Short answer:

  • Java 5–8: Parallel GC on "server-class" machines (≥ 2 CPUs and ≥ 2 GB RAM), otherwise Serial.
  • Java 9 onward: G1 is the default on server-class machines (JEP 248). That's still true in current releases.
  • Serial is still chosen automatically when the JVM sees fewer than 2 CPUs or less than about 1792 MB of memory, which often happens in small containers. Many teams are surprised to find Serial GC running in their pods. Set -XX:+UseG1GC explicitly, or give the container at least 2 CPUs.

Common trap: the source says Parallel stayed the default until Java 10, and that G1 arrived in Java 11. G1 became the default in Java 9.

Q9. How does G1 work, and how does it differ from CMS? How does G1 differ from ZGC?

Short answer:

  • How G1 works:
    • The heap is split into equal regions (1–32 MB), each dynamically assigned as Eden, Survivor, Old or Humongous.
    • Young collections evacuate live objects from young regions (STW, parallel).
    • When old occupancy passes the IHOP threshold, a concurrent marking cycle computes the liveness of each region.
    • Then mixed collections evacuate the old regions with the most garbage first (hence "Garbage-First"), within the pause-time goal (-XX:MaxGCPauseMillis).
    • Remembered sets track references between regions, so regions can be collected independently.
    • Because evacuation copies, G1 compacts incrementally, which avoids fragmentation.
  • G1 vs CMS:
    • CMS never compacted the old generation (it used free lists). That led to fragmentation, and eventually concurrent mode failures, which meant long single-threaded Full GCs.
    • G1 is region-based, compacting, and pause-target driven.
    • CMS is gone (removed in Java 14).
  • G1 vs ZGC (DXB-603):
    • G1's evacuation is stop-the-world, so pauses grow with the live objects to copy (typically tens of milliseconds).
    • ZGC relocates objects concurrently, using load barriers and coloured pointers, so pauses stay under a millisecond regardless of heap size.
    • The costs: somewhat lower throughput, and more CPU and memory headroom needed.

Q10. What is a GC pause? What causes it, and how do you reduce it?

Short answer: A GC pause is time when application threads are stopped (at a safepoint) so the collector can work safely: scanning roots, evacuating or copying objects, or doing a full compaction. Causes of long pauses:

  • a large live set in the young generation (copy cost);
  • humongous allocations;
  • Full GCs (evacuation failures, a Metaspace threshold, System.gc(), promotion failure);
  • reference processing, with many soft or weak references and finalizers;
  • time-to-safepoint delays;
  • the OS: swapping, transparent huge pages compaction, CPU throttling in containers.

Ways to reduce them:

  • Allocate less (fewer temporary objects, streaming instead of loading everything, primitives).
  • Right-size the heap and young generation.
  • Keep G1's pause target realistic.
  • Avoid humongous objects (increase G1HeapRegionSize).
  • Remove System.gc() calls.
  • Give containers enough CPU.
  • Switch to generational ZGC for strict latency SLOs.

Learn it in depth → GC Tuning & Diagnostics

Q11. What is a stop-the-world (STW) event? What causes STW events?

Short answer: An STW event is a safepoint operation during which all application threads are paused. GC causes:

  • young evacuation (G1, Parallel, Serial);
  • remark and cleanup phases;
  • Full GCs;
  • the brief root-scanning pauses in ZGC and Shenandoah.

Non-GC STW causes: deoptimisation of many methods, class redefinition (agents, debuggers), thread dumps, and some JVMTI operations. Historically, biased-lock revocation too.

The total stall is the time to reach the safepoint plus the time inside it. -Xlog:safepoint* shows both.

Q12. What causes frequent Full GCs?

Short answer:

  • An old generation that's too full: a memory leak, or a live set that's close to -Xmx, so every GC reclaims little. This leads to a GC death spiral, and finally OutOfMemoryError: GC overhead limit exceeded (Parallel).
  • G1 evacuation failure ("to-space exhausted"), or concurrent marking that can't keep up with the allocation or promotion rate. Start marking earlier (-XX:G1ReservePercent, adaptive IHOP), or give the heap more headroom.
  • Humongous allocation pressure.
  • Metaspace reaching its high-water mark (class generation, classloader leaks).
  • Explicit System.gc(), including from libraries and RMI's DGC.
  • Premature promotion: a young generation or survivor spaces that are too small, so short-lived objects flood the old generation.
  • Heap dump or diagnostic commands (jmap -histo:live forces a Full GC).

Check the GC log's "Pause Full (reason)" lines to know which one it is.

Q13. What is GC compaction, and why does it matter?

Short answer: Compaction moves live objects together, leaving contiguous free space. That:

  • prevents fragmentation, where there's enough total free memory, but no single hole big enough for a large object, causing a premature OOM or a Full GC;
  • keeps allocation as a cheap bump-the-pointer operation;
  • improves locality.

How each collector compacts:

  • Copying young collectors compact implicitly.
  • G1 compacts incrementally, through region evacuation.
  • ZGC and Shenandoah compact concurrently.
  • CMS's lack of compaction was its fatal flaw.

Q14. What are promotion failure and allocation failure?

Short answer:

  • Allocation failure: Eden (or the TLAB refill) can't satisfy an allocation. This is the normal trigger for a young GC ("Pause Young (Allocation Failure)" in older logs). It isn't an error.
  • Promotion failure: during a young GC, surviving objects must be promoted to the old generation, but it has no room (full, or too fragmented). The collector falls back to an expensive Full GC. In G1, the equivalent is evacuation failure / to-space exhausted.

The causes are an old generation that's too small, a leak, premature promotion, or (in CMS) fragmentation.

Q15. What are the challenges of distributed garbage collection (DGC)?

Short answer: DGC reclaims objects that are referenced remotely (Java RMI's DGC uses leases: a client periodically renews its lease on remote objects, and expired leases allow collection). The challenges:

  • No global view: references cross machines, and there are network partitions.
  • Failures: a crashed client never releases its references, which is why lease timeouts exist.
  • Distributed cycles can't be detected by reference counting.
  • Latency and overhead from renewal messages. RMI DGC used to trigger periodic full GCs (sun.rmi.dgc.*.gcInterval).
  • Consistency under message loss and duplication.

Key points to cover:

  • Modern systems avoid remote object references altogether: stateless services, and explicit resource lifecycles (TTLs and leases in Redis, Zookeeper or etcd).

Follow-up questions this topic invites — and their answers

Q: What does -XX:MaxGCPauseMillis really do in G1? A: It sets a soft target. G1 sizes the young generation and chooses how many old regions to include in mixed collections, to try to meet it. Setting it too low makes G1 shrink the young generation, and collect more often, which lowers throughput, and can still miss the target.

Q: How much CPU and memory headroom does ZGC need? A: Concurrent collectors need spare CPU for their GC threads while the application runs, and heap headroom: allocation continues during collection. If allocation outpaces collection, you get allocation stalls. Give ZGC a larger heap than the live set (for example 2–3×), and watch for "Allocation Stall" in its logs.

Q: Why is the young generation collected with copying? A: Most objects die young (the weak generational hypothesis). Copying cost is proportional to the few survivors, and garbage costs nothing. It also compacts the survivors for free.

Q: What is card marking or a remembered set? A: A write-barrier-maintained structure recording old-to-young (or cross-region, in G1) references, so a young collection doesn't have to scan the whole old generation to find roots into the young generation.

Previous

JIT Compilation & Runtime Optimisations — Interview Questions

Next

JVM Tuning, GC Logs & Memory Footprint — Interview Questions

AI Tutor

Lesson: Garbage Collectors Deep Dive — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.