Reference Types: Weak, Soft, Phantom
Beyond strong references (normal object references), Java provides WeakReference, SoftReference, and PhantomReference. They allow the GC to collect objects when memory is needed, enabling cache and lifecycle patterns.
Strong ref = holding a dog on a leash. Soft ref = a sticky note on the fridge (removed only when you need fridge space). Weak ref = writing a name in sand (gone at the next wave/GC). Phantom ref = a ghost that haunts the ReferenceQueue after death.
WeakReference: collected at the next GC cycle once no strong references remain — used in WeakHashMap for caches where entries should disappear when the key is GC'd. SoftReference: collected only when the JVM is under memory pressure (before OOM) — good for memory-sensitive caches. PhantomReference: always returns null on get(); used with ReferenceQueue to perform post-finalization cleanup (replacing finalize()). All three can be registered with a ReferenceQueue — when the referent is collected, the Reference object is enqueued for cleanup notification. Cleaner (Java 9+) is the preferred finalization mechanism over finalize().
The GC processes reference queues after marking — once a weakly-reachable object is identified, its WeakReference is enqueued and the referent can be freed. WeakHashMap's Entry extends WeakReference<K>; when the key is GC'd, the Entry appears in the queue and a background expunge removes it on next map access. PhantomReference's get() always returns null by design — the cleanup action must be performed by the thread draining the ReferenceQueue, not by reading the referent. The Cleaner API wraps this pattern: register a Runnable cleanup action that runs after the object becomes phantom-reachable. finalize() is deprecated (Java 9) and deprecated for removal (Java 18) — it still exists but emits warnings; it was slow, unpredictable, and could resurrect objects. Use Cleaner instead.
SoftReferences are collected only under memory pressure — ideal for in-memory caches that should yield memory to prevent OOM. WeakReferences are collected at the next GC — used in WeakHashMap where entries should automatically expire when the key is no longer referenced. PhantomReferences are for post-GC cleanup actions (replacing the deprecated finalize()) — register a Cleaner action that runs after the object is collected, with no risk of object resurrection. All three integrate with ReferenceQueue for cleanup notification.
WeakHashMap keys must be objects with identity-based equality (not Strings or other interned/cached objects) — interned strings are always strongly referenced by the string pool, so WeakHashMap<String, V> entries are never collected.