Understanding Java Reference Types and Their Practical Uses

Object Reclamation in the JVM

Reachability Analysis

The JVM uses the reachability analysis algorithm to determine which objects can be garbage collected. This approach identifies a set of root objects that are guaranteed to be alive, then traces references to find all objects reachable from these roots. Any object not reachable from a GC root becomes eligible for collection.

GC Root Categories

Objects that serve as GC roots include:

  • Local variables in JVM stack frames
  • Method parameters and temporary variables on call stacks
  • Static fields from the method area
  • String constant pool references
  • JNI handles from native method stacks
  • Objects synchronized with the synchronized keyword
  • JVM internal objects (classloaders, exception objects)
  • JMX and JVMTI callbacks

You can analyze heap dumps using jmap:

jmap -dump:format=b,live,file=heap.bin <pid>

Java Reference Type Hierarchy

Strong Reference

The default reference type in Java. Any object reachable through a chain of strong references from a GC root will never be collected. This is what most Java code uses:

Object strong = new Object();

Soft Reference (SoftReference)

Objects with only soft references remain in memory until the JVM determines memory is insufficient. When allocation fails, the garbage collector will reclaim soft-referenced objects before throwing OutOfMemoryError.

Key characteristic: Collected only when memory pressure exists.

Weak Reference (WeakReference)

Weak references do not protect objects from collection. Whenever the garbage collector runs, weak-referenced objects are reclaimed regardless of memory availability.

Key characteristic: Collected on every GC cycle.

Phantom Reference (PhantomReference)

Phantom references must be paired with a ReferenceQueue. The referenced object cannot be accessed via get() - it always returns null. When an object is collected, the phantom reference is enqueued, allowing cleanup actions.

Common use case: Coordinating cleanup of off-heap memory like direct ByteBuffers.

Finalizer Reference (FinalReference)

Used internally for the finalize() mechanism. The Finalizer thread invokes finalize() on objects, but this happens during a second GC pass. Due to low thread priority, finalization is unreliable.

Reference Type Comparison

Reference Type GC Behavior Common Usage
Strong Never collected while referenced Default
Soft Collected when memory is low Memory-sensitive caches
Weak Collected on every GC Canonicalized mappings
Phantom Always returns null Direct memory cleanup
Finalizer Second GC pass after finalize Legacy cleanup (avoid)

Practical Application: Soft Reference for Large Cache

When caching large objects that should be released under memory pressure, soft references provide automatic memory management:

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

public class CacheDemo {
    private static final int UNIT = 4 * 1024 * 1024;
    
    public static void main(String[] args) {
        List<SoftReference<byte[]>> cache = new ArrayList<>();
        
        for (int i = 0; i < 5; i++) {
            SoftReference<byte[]> ref = new SoftReference<>(new byte[UNIT]);
            System.out.println("Created entry #" + (i + 1));
            cache.add(ref);
        }
        
        System.out.println("Cache size: " + cache.size());
        
        for (SoftReference<byte[]> ref : cache) {
            System.out.println("Entry: " + ref.get());
        }
    }
}

Run with limited heap: -Xmx20m

The output shows that only the last entry survives when memory becomes insufficient:

Created entry #1
Created entry #2
Created entry #3
[GC collections...]
Created entry #4
[Full GC...]
Created entry #5
Cache size: 5
null
null
null
null
[B@7ea987ac

Using Reference Queues for Cleanup

When reference objects themselves need cleanup, associate them with a ReferenceQueue:

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

public class QueueDemo {
    private static final int UNIT = 4 * 1024 * 1024;
    
    public static void main(String[] args) {
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        List<SoftReference<byte[]>> activeRefs = new ArrayList<>();
        
        for (int i = 0; i < 5; i++) {
            SoftReference<byte[]> ref = new SoftReference<>(
                new byte[UNIT], queue
            );
            activeRefs.add(ref);
        }
        
        // Remove references that have been enqueued
        Reference<? extends byte[]> cleaned;
        while ((cleaned = queue.poll()) != null) {
            activeRefs.remove(cleaned);
        }
        
        System.out.println("Active references: " + activeRefs.size());
    }
}

Weak Reference in Cache Scenarios

Weak references suit scenarios where data can be reconstructed if discarded:

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

public class WeakCache<K, V> {
    private final Map<K, WeakReference<V>> cache = new HashMap<>();
    
    public V get(K key) {
        WeakReference<V> ref = cache.get(key);
        return ref != null ? ref.get() : null;
    }
    
    public void put(K key, V value) {
        cache.put(key, new WeakReference<>(value));
    }
}

This implementation automatically discards entries when the JVM needs memory, allowing the garbage collector to reclaim the values.

Summary

Java provides five reference types offering different garbage collection behaviors. Strong references are the default and keep objects alive indefinitely. Soft references survive until memory pressure forces collection, making them suitable for memory-sensitive caches. Weak references allow immediate collection on any GC cycle, ideal for canonicalization maps. Phantom references enable post-collection cleanup coordination, particularly for off-heap resources. Finalizer references exist for backward compatibility but should be avoided due to unreliable timing.

Tags: java JVM garbage collection Memory Management Reference Types

Posted on Mon, 24 Aug 2026 16:26:16 +0000 by morleypotter