Understanding Java Garbage Collection: Algorithms, References, and Finalization

This article explains Java's garbage collection mechanisms, covering memory regions, the limitations of reference counting, the root search algorithm, various reference types, the two-phase marking process, and how the method area is reclaimed, illustrated with code examples and diagrams.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Understanding Java Garbage Collection: Algorithms, References, and Finalization

1. Overview of Java Garbage Collection

Java runtime memory is divided into several areas. The program counter, virtual machine stack, and native method stack are created and destroyed with each thread, and their stack frames allocate memory that is known when the class is loaded, so they do not require explicit garbage collection. The heap and method area, however, allocate memory dynamically at runtime, and the garbage collector focuses on reclaiming memory in these regions.

2. Reference Counting Algorithm

In interviews, one might suggest adding a reference counter to each object, incrementing it on each new reference and decrementing it when a reference is lost; an object with a count of zero would be considered unreachable. Although this algorithm is simple and efficient, Java does not use it because it cannot handle cyclic references.

Example of a cycle:

public class ReferenceCountingGC {
    public Object instance = null;
    private static final int _1MB = 1024 * 1024;
    private byte[] bigSize = new byte[2 * _1MB];
    public static void testGC() {
        ReferenceCountingGC objA = new ReferenceCountingGC();
        ReferenceCountingGC objB = new ReferenceCountingGC();
        objA.instance = objB;
        objB.instance = objA;
        objA = null;
        objB = null;
        System.gc();
    }
}

The JVM still collects the two objects, showing that Java does not rely on reference counting.

3. Root Search Algorithm

Java GC uses a "root search" algorithm. Starting from GC roots, it traverses the object graph; any object not reachable from a root forms an unreachable reference chain and is eligible for collection.

Typical GC roots in Java include:

References in the VM stack (local variable tables).

Static fields in the method area.

Constants in the method area.

JNI (native) references in the native method stack.

Objects that are unreachable from these roots, such as object5, object6, and object7 in the diagram, will be reclaimed.

GC roots diagram
GC roots diagram

4. Types of References

Java defines four reference strengths, from strongest to weakest:

Strong Reference : ordinary references (e.g., Object obj = new Object();) that prevent the object from being collected.

Soft Reference : used for memory‑sensitive caches; the object is reclaimed only when the JVM is about to throw an OutOfMemoryError.

Weak Reference : the object is reclaimed at the next GC cycle regardless of memory pressure.

Phantom (Virtual) Reference : does not affect object lifetime; it is used only to receive a notification after the object has been reclaimed.

5. Two‑Phase Marking During GC

When an object is found unreachable, the GC performs two marking steps. First, it marks the object and checks whether it overrides finalize(). If finalize() is needed, the object is placed in an internal F‑Queue and a low‑priority finalizer thread later invokes finalize(). The finalizer can resurrect the object by creating a new strong reference.

public class FinalizeEscapeGC {
    public static FinalizeEscapeGC SAVE_HOOK = null;
    public void isAlive() {
        System.out.println("yes, i am still alive");
    }
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed!");
        SAVE_HOOK = this; // resurrect
    }
    public static void main(String[] args) throws Throwable {
        SAVE_HOOK = new FinalizeEscapeGC();
        SAVE_HOOK = null;
        System.gc();
        Thread.sleep(500);
        if (SAVE_HOOK != null) {
            SAVE_HOOK.isAlive();
        } else {
            System.out.println("no, i am dead");
        }
        // second attempt – finalize will not run again
        SAVE_HOOK = null;
        System.gc();
        Thread.sleep(500);
        if (SAVE_HOOK != null) {
            SAVE_HOOK.isAlive();
        } else {
            System.out.println("no, i am dead");
        }
    }
}

Running the program shows that the first object can rescue itself once, but the second attempt fails because finalize() is invoked at most once by the JVM.

6. Collecting the Method Area

The method area (or PermGen in older HotSpot) can also be garbage‑collected, though its efficiency is lower than that of the heap. The GC reclaims two kinds of data: unused constants and classes that satisfy three conditions: all instances are gone, the defining ClassLoader is reclaimed, and the java.lang.Class object is no longer referenced. Class unloading can be controlled with JVM options such as -Xnoclassgc and monitored with -verbose:class, -XX:+TraceClassLoading, and -XX:+TraceClassUnloading.

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.

javaMemory ManagementGarbage CollectionfinalizeReference Types
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

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.