This is one of the most fundamental and fascinating topics in Java memory management. Let’s go through all 4 types of references in Java, how the Garbage Collector (GC) treats them, and when you’d use each one.
🧠 Java Reference Types Overview
Java has four types of object references:
Type | Prevents GC? | Cleared when? | Use case |
---|---|---|---|
Strong | ✅ Yes | Only when no reference at all | Normal object usage |
Soft | ☁️ Maybe | When memory is low | Memory-sensitive caches |
Weak | ❌ No | As soon as no strong reference exists | Temporary mappings, WeakHashMap |
Phantom | 👻 No | After finalization, before GC reclaims | Post-mortem cleanup, advanced use |
🔹 1. Strong Reference (Default)
This is the “normal” reference in Java:
Object obj = new Object(); // strong reference
- As long as
obj
is reachable, the object is not eligible for GC. - Most variables you use are strong references.
📌 When to use: All standard code.
🔸 2. Soft Reference
SoftReference<Object> ref = new SoftReference<>(new Object());
- The object is kept alive until memory is low.
- GC may collect it only if it needs memory.
- Used for caching data that’s “nice to keep” but not critical.
📌 When to use: In-memory caches, image loaders, LRU caches.
🔸 3. Weak Reference
WeakReference<Object> ref = new WeakReference<>(new Object());
- The object is collected as soon as there are no strong references to it.
- You can still access the object via
ref.get()
until it’s GC’d. - Common in
WeakHashMap
, observer patterns, memory-sensitive tools.
📌 When to use: Maps, non-blocking listeners, temporary metadata.
🔸 4. Phantom Reference
PhantomReference<Object> ref = new PhantomReference<>(obj, referenceQueue);
- You can’t get the object (
ref.get()
always returnsnull
). - Used to track when an object is truly gone (after finalization).
- GC will enqueue the
PhantomReference
in aReferenceQueue
.
📌 When to use: Advanced cases like custom memory managers, native cleanup, or when you need to run code after GC.
🔁 Reference Lifecycle Diagram
[ Strong ] --> [ Object ] --> survives GC
[ Soft ] --> [ Object ] --> survives GC until memory is low
[ Weak ] --> [ Object ] --> GC removes it as soon as no strong ref
[ Phantom] --> [ Object ] --> GC removes it, you get notified via queue
A ReferenceQueue<T>
is a special queue in Java that’s used to receive notifications when referenced objects are garbage collected.
When a referent (the object being referred to) is GC’d, its reference (WeakReference, SoftReference, PhantomReference) is added to the
ReferenceQueue
, if one is attached.
ReferenceQueue<Object> queue = new ReferenceQueue<>();
WeakReference<Object> weakRef = new WeakReference<>(new Object(), queue);
// No strong references now → GC can collect it
System.gc();
Reference<?> polled = queue.poll(); // Will contain `weakRef` if GC collected the object
🧩 Why is this useful?
Because weak/soft/phantom references don’t trigger callbacks on their own — they’re passive.
If you want to:
- Be notified when an object is collected
- Do cleanup, resource release, or logging
- Manage your own memory-sensitive cache or pool
→ then ReferenceQueue
is how you listen for the GC to say:
“Hey, this object is gone now — you can react.”