Java Garbage Collection: GC Roots, Generational Collectors & ZGC

In languages like C and C++, developers must manually allocate and deallocate memory using malloc() and free(). One forgotten free creates memory leaks; a premature free causes fatal segmentation faults. In Java, Garbage Collection (GC) is entirely automated, continuously tracking object lifecycles and reclaiming memory silently in the background.

Java Generational Garbage Collection: Eden, Survivor, and Old Generation

1. Reachability Analysis & GC Roots

An object is eligible for garbage collection when there is no path of references linking it to a GC Root. Primary GC Roots include:

  • Thread Stack Local Variables: Parameters and local variables inside currently executing method frames.
  • Static Variables: References held by loaded classes in Metaspace.
  • JNI (Java Native Interface) Handles: Global and local native pointers in C/C++ code.
  • Active Java Threads: Running Thread objects.

2. The Three Core Phases of Garbage Collection

  1. Mark: The GC traverses the reference graph starting from GC Roots, marking all reachable (live) objects.
  2. Sweep: Unmarked memory slots containing dead objects are cleared and marked as available for future allocations.
  3. Compact: Live objects are shifted together to contiguous memory addresses to eliminate fragmented empty holes.

3. Generational GC Lifecycle

PhaseGenerationEvent NameDescription
1. AllocationEden SpaceNew ObjectObjects are instantiated in Eden via new.
2. Minor GCYoung (Eden + S0)ScavengeWhen Eden fills, Minor GC triggers. Live objects copy to Survivor space (S1) with age = 1. Eden is wiped clean.
3. PromotionYoung $\rightarrow$ OldTenuringObjects that survive repeated Minor GCs (tenuring threshold, default 15) are promoted to the Old (Tenured) Generation.
4. Major / Full GCYoung + Old + MetaspaceStop-The-WorldCleans Old Generation. Scans entire heap; triggers a Stop-The-World (STW) pause.

4. Modern Java Garbage Collectors Compared

CollectorJVM FlagCharacteristicsBest Use Case
Serial GC-XX:+UseSerialGCSingle-threaded, Stop-The-WorldSmall CLI tools, micro-containers (< 512 MB RAM)
Parallel GC-XX:+UseParallelGCMulti-threaded throughput-focusedBatch processing, offline scientific calculations
G1 GC (Default)-XX:+UseG1GCRegion-based, predictable pausesGeneral enterprise web servers, heaps from 4 GB to 64 GB
ZGC (Modern)-XX:+UseZGCConcurrent, sub-millisecond pausesUltra-low latency financial, real-time gaming, > 16 GB heaps

Making Objects Eligible for Garbage Collection

public class GCDemo {
    public static void main(String[] args) {
        // Case 1: Nullifying reference
        String s1 = new String("Veewom");
        s1 = null; // Original String object is now unreachable and eligible for GC

        // Case 2: Reassigning reference
        String a = new String("First");
        String b = new String("Second");
        a = b; // "First" object is now orphaned and eligible for GC

        // Case 3: Objects created inside local method scope
        createTempData(); // Any objects inside createTempData() without escaping are collected
        
        // Suggesting GC (Never guaranteed in production!)
        System.gc();
    }

    private static void createTempData() {
        byte[] temp = new byte[1024]; // dies when method stack frame pops
    }
}
BCA / University Exam Corner
  • Viva Question: Does calling System.gc() guarantee that garbage collection will run immediately?
    Answer: No! System.gc() is merely a polite hint to the JVM that you would prefer garbage collection to run. The JVM specification explicitly gives no guarantee that the GC will execute immediately or at all. In enterprise production systems, System.gc() is often disabled using -XX:+DisableExplicitGC.
  • Deprecated Notice: The finalize() method was officially deprecated in Java 9 and marked for removal due to unpredictable execution timing and resurrection vulnerabilities. Use AutoCloseable and Cleaner instead.

Frequently Asked Questions (FAQ)

Q1. How does the JVM Garbage Collector determine if an object is eligible for collection?
The JVM uses Reachability Analysis starting from GC Roots (active thread stack frames, static variables, JNI references). If an object in Heap memory cannot be reached through any reference chain tracing back to an active GC Root, the object is designated as unreachable and eligible for garbage collection.
Q2. What is the Weak Generational Hypothesis?
Empirical studies across decades of software development show that the vast majority of objects die very shortly after allocation (e.g., local method variables, temporary StringBuilder buffers). The JVM separates memory into Young and Old generations so the GC can rapidly collect young garbage frequently without scanning the entire heap.
Q3. What is ZGC (Z Garbage Collector) and why is it revolutionary?
ZGC is a scalable low-latency garbage collector available in modern Java (production-ready since Java 15, generational in Java 21). It performs all expensive phases (marking, relocation, reference processing) concurrently with application threads, achieving sub-millisecond maximum pause times even on multi-terabyte heaps.

Explore Related Java Tutorials

Accelerate your Java mastery by studying these tightly connected core tutorials:

JVM Memory Architecture →

Eden, Survivor, and Tenured generation layout.

JVM Internals →

The Execution Engine and ClassLoader.

Java Multithreading →

Understanding thread stacks as GC roots.

Java Virtual Threads →

Modern concurrency impact on garbage collection.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!