GC roots and reachability
The collector starts from a fixed set of roots and walks. Whatever it cannot reach is garbage.
Open this lesson in the learning hubKey points
- GC roots are the starting points: locals on any thread stack, static fields, JNI references, and live threads themselves.
- The collector marks everything reachable from those roots. Whatever is left unmarked is dead, however tangled it looks.
- Reference cycles collect fine. Java does not count references, so two objects pointing at each other are still garbage.
- That is why a
staticfield is dangerous. It is a root, so everything hanging off it lives as long as the class does. - A running thread is a root too, and so is every object its stack can still reach.
Example
import java.lang.ref.WeakReference;
public class Main {
static class Node { Node peer; byte[] payload = new byte[512]; }
static Node root; // a static field is a GC root
public static void main(String[] args) throws InterruptedException {
Node a = new Node();
Node b = new Node();
a.peer = b;
b.peer = a; // a reference cycle
WeakReference<Node> watch = new WeakReference<>(a);
root = a;
a = null;
b = null;
System.gc();
Thread.sleep(50);
System.out.println("reachable from the static root -> alive? " + (watch.get() != null));
root = null; // now only the cycle is left
for (int i = 0; i < 5 && watch.get() != null; i++) { System.gc(); Thread.sleep(50); }
System.out.println("root cleared, cycle intact -> alive? " + (watch.get() != null));
System.out.println();
System.out.println("Cycles are collected fine. The question is never who points at me,");
System.out.println("it is whether any GC root can still walk to me.");
}
}
The question is not who points at you. It is whether a root can reach you.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the JVM course, and every lesson in it is listed on the JVM contents page.