Fundamentals 22 min read

Understanding Java Reference Types and Garbage Collection in JDK 8

This article explains the four kinds of Java references—strong, soft, weak, and phantom—how they interact with the garbage collector, the role of ReferenceQueue, and provides practical code examples and JVM internal details to help developers manage object lifecycles effectively.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Understanding Java Reference Types and Garbage Collection in JDK 8

In Java, object reachability is determined by reference types, which are the basis of garbage‑collection algorithms such as reference counting and reachability analysis.

Reference

Java distinguishes between primitive types (byte, short, int, long, float, double, char, boolean) and reference types (classes, interfaces, arrays, enums, annotations). A reference works like a pointer in C, allowing programs to manipulate heap objects.

Four Reference Strengths (JDK 1.2+)

Strong Reference

Soft Reference

Weak Reference

Phantom (or Ghost) Reference

The JVM treats each kind differently, enabling developers to influence object lifetimes.

Strong Reference

A typical assignment such as Object obj = new Object(); creates a strong reference. Objects reachable through strong references are never reclaimed, even if memory is low, which can lead to memory leaks unless the reference is cleared or goes out of scope.

public class StrongReferenceDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = o1;
        o1 = null;
        System.gc();
        System.out.println(o1); // null
        System.out.println(o2); // java.lang.Object@xxxx
    }
}

In the demo, o2 holds a strong reference to the object, so it survives GC.

Soft Reference

Implemented via java.lang.ref.SoftReference , soft references are cleared only when the JVM is about to run out of memory. They are ideal for caches that should stay in memory while space permits.

// VM options: -Xms5m -Xmx5m
public class SoftReferenceDemo {
    public static void main(String[] args) {
        softRefMemoryEnough();
        System.out.println("--- Memory insufficient case ---");
        softRefMemoryNotEnough();
    }
    private static void softRefMemoryEnough() {
        Object o1 = new Object();
        SoftReference
s1 = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(s1.get());
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(s1.get());
    }
    private static void softRefMemoryNotEnough() {
        Object o1 = new Object();
        SoftReference
s1 = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(s1.get());
        o1 = null;
        byte[] bytes = new byte[10 * 1024 * 1024]; // allocate 10 MiB
        System.out.println(o1);
        System.out.println(s1.get());
    }
}

When memory is scarce, the soft‑referenced object is reclaimed, as shown by the OutOfMemoryError output.

Weak Reference

Created with java.lang.ref.WeakReference , weak references are cleared at the next GC cycle regardless of memory pressure. They are commonly used for canonicalizing maps such as WeakHashMap .

public class WeakReferenceDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        WeakReference
w1 = new WeakReference<>(o1);
        System.out.println(o1);
        System.out.println(w1.get());
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(w1.get()); // likely null
    }
}

Phantom Reference

Phantom (or ghost) references, implemented via java.lang.ref.PhantomReference , never return the referent (their get() always yields null ). They must be paired with a ReferenceQueue to receive a notification when the object is finalized, allowing custom cleanup actions.

public class PhantomReferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        Object o1 = new Object();
        ReferenceQueue
queue = new ReferenceQueue<>();
        PhantomReference
phantom = new PhantomReference<>(o1, queue);
        System.out.println(o1);
        System.out.println(queue.poll()); // null
        System.out.println(phantom.get()); // null
        o1 = null;
        System.gc();
        Thread.sleep(3000);
        System.out.println(queue.poll()); // reference enqueued
        System.out.println(phantom.get()); // still null
    }
}

ReferenceQueue

A ReferenceQueue receives references whose referents have been reclaimed. Both SoftReference , WeakReference , and PhantomReference can be constructed with a queue, enabling applications to react when an object disappears.

JDK 8 Reference Implementation (Key Points)

The abstract class java.lang.ref.Reference is the common superclass for all reference types. It stores the referent, an optional queue, and a linked‑list pointer used by the JVM’s internal ReferenceHandler thread.

public abstract class Reference
{
    private T referent;
    volatile ReferenceQueue
queue;
    volatile Reference next;
    private transient Reference
discovered;
    private static Reference
pending = null;
    Reference(T referent) { this(referent, null); }
    Reference(T referent, ReferenceQueue
queue) {
        this.referent = referent;
        this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
    }
    public T get() { return referent; }
    public void clear() { referent = null; }
    public boolean isEnqueued() { return queue == ReferenceQueue.ENQUEUED; }
    public boolean enqueue() { return queue.enqueue(this); }
}

The JVM creates a high‑priority daemon thread named Reference Handler that moves pending references onto their queues, enabling the application‑level code to poll or remove them.

Practical Uses

Soft references are used in cache implementations (e.g., MyBatis SoftCache ), weak references power WeakHashMap and ThreadLocal internals, while phantom references allow post‑finalization cleanup.

For further reading, see the original sources: Juejin article, KD Gregory’s blog, CSDN tutorial, Throw‑able Club post, and the book "深入理解Java虚拟机".

JavaJVMGarbage CollectionReferenceWeakReferencePhantomReferenceSoftReference
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

login 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.