What Are GC Roots? Understanding JVM Garbage Collection Basics

The article explains the concept of GC Roots in the JVM, detailing the four main types—stack variables, static fields, constant pool references, and JNI references—along with code examples, and describes how these roots determine object liveness during garbage collection.

Xuanwu Backend Tech Stack
Xuanwu Backend Tech Stack
Xuanwu Backend Tech Stack
What Are GC Roots? Understanding JVM Garbage Collection Basics

In the JVM's garbage collection mechanism, GC Roots are a set of special references that serve as the starting points for determining whether objects are alive. Starting from these roots, the collector traverses the object graph; objects reachable from the roots are marked as alive, while those not reachable are considered garbage and eligible for reclamation.

1. Variables in the JVM stack (local variables)

When a Java method executes, each method creates a stack frame, and the local variable table stores method parameters and locally defined variables. The references held by these variables (e.g., MyClass obj) are themselves GC Roots, keeping the heap objects they point to alive.

public class GCRootsTest {
    public static void main(String[] args) {
        // obj is a local variable (GC Root) referencing a MyClass object on the heap
        MyClass obj = new MyClass();

        // When the method ends, the stack frame is destroyed, and obj is removed as a GC Root
        // The MyClass object loses all GC Root references and becomes eligible for garbage collection
    }
}

Note: the GC Root is the obj variable (the reference), not the new MyClass() object itself.

2. References from static fields in the method area

Static variables (declared with static) are globally visible and have a lifecycle tied to the class, so references held by static fields are also GC Roots.

public class StaticReferenceClass {
    // staticObj is a static variable (GC Root)
    static Object staticObj = new Object();
}

Objects referenced by static variables remain alive until the class is unloaded, which typically occurs only when the class loader is reclaimed.

3. References from static constants

Static final references : If a constant is declared with static final and its type is a reference (e.g., public static final Object CONST = new Object();), the static field is a GC Root that directly references a heap object.

Runtime constant pool references : String literals (e.g., String s = "abc";) are stored in the heap's string constant pool, but their references are held indirectly through the class's metadata in the runtime constant pool. The Class object itself is a GC Root, so the literal remains reachable.

Final primitive constants : Primitive constants such as final int x = 1; do not involve heap object references and therefore are unrelated to GC Roots.

When a class is unloaded, the reference chain from its constant pool is broken, allowing the associated string objects to be reclaimed.

public class MyClass {
    public static final Object CONST = new Object(); // CONST is a static variable (GC Root)
}

4. JNI references from native methods

References to Java objects made inside native (JNI) methods are treated as GC Roots, ensuring that objects used by native code are not reclaimed while the native method is executing.

public class JNIGCRoots {
    // Declare native method
    private native void nativeMethod();

    static {
        // Load native library
        System.loadLibrary("JNIGCRoots");
    }

    public static void main(String[] args) {
        JNIGCRoots instance = new JNIGCRoots();
        // During nativeMethod execution, 'instance' may become a GC Root via JNI
        instance.nativeMethod();
    }
}

During the execution of the native method, any Java objects referenced by JNI are considered GC Roots; after the method returns, if no other references exist, those objects become eligible for garbage collection.

Active thread instances : Objects representing running threads (e.g., Thread instances) are GC Roots.

Synchronized monitor (lock) objects : Objects held by a synchronized block are GC Roots until the lock is released.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaJVMmemory managementGarbage CollectionGC Roots
Xuanwu Backend Tech Stack
Written by

Xuanwu Backend Tech Stack

Primarily covers fundamental Java concepts, mainstream frameworks, deep dives into underlying principles, and JVM internals.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.