Question
What is the difference between java.lang.ref.WeakReference and java.lang.ref.SoftReference in Java? In particular, how does the garbage collector treat each type of reference, and when should each one be used?
Short Answer
Java provides WeakReference and SoftReference for cases where an object should not be kept alive by a normal strong reference. A weakly referenced object is usually collected as soon as it becomes otherwise unreachable. A softly referenced object may remain available longer, but the JVM can clear it when memory is needed. By the end, you will know their garbage-collection behavior, limitations, and appropriate use cases.
Concept
A normal Java variable holds a strong reference:
User user = new User();
As long as user is reachable, the garbage collector (GC) must keep the User object in memory.
The classes in java.lang.ref let you hold references that do not necessarily keep an object alive:
WeakReference<T>holds a weak reference.SoftReference<T>holds a soft reference.
When an object is reachable only through a WeakReference, it is weakly reachable. The GC can clear that reference during a collection cycle. In practice, you should assume a weakly referenced object can disappear at any time after its last strong reference is gone.
When an object is reachable only through a SoftReference, it is softly reachable. The JVM may keep it around for a while, but it can clear the reference when it needs memory. The Java specification does not promise exactly when this happens.
This matters because get() can return either the referenced object or null:
T value = reference.get();
A result means the reference has been cleared, so your program must handle it safely.
Mental Model
Think of memory as a storage room and the garbage collector as the person deciding what can be removed.
- A strong reference is like a signed ownership document: the item must stay.
- A soft reference is like a note saying: “Keep this item if there is space; throw it away if storage is needed.”
- A weak reference is like a temporary pointer on a whiteboard: once no one officially owns the item, the cleaner can erase both the item and the pointer.
The important rule is that a soft or weak reference is not a promise that an object will still exist when you ask for it. Always check the result of get().
Syntax and Examples
Create soft and weak references with their generic type:
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
public class ReferenceExample {
public static void main(String[] args) {
String strongValue = new String("report data");
SoftReference<String> softRef = new SoftReference<>(strongValue);
WeakReference<String> weakRef = new WeakReference<>(strongValue);
System.out.println(softRef.get()); // report data
System.out.println(weakRef.get()); // report data
strongValue = null;
// The objects may still be available now, but GC may clear them later.
String fromSoftReference = softRef.get();
String fromWeakReference = weakRef.get();
if (fromSoftReference != null) {
System.out.println("Soft value is still available");
}
if (fromWeakReference != null) {
System.out.println();
}
}
}
Step by Step Execution
Consider this example:
import java.lang.ref.WeakReference;
public class WeakTrace {
public static void main(String[] args) {
String message = new String("temporary");
WeakReference<String> ref = new WeakReference<>(message);
message = null;
String value = ref.get();
System.out.println(value);
}
}
Step by step:
new String("temporary")creates aStringobject.messageis a strong reference to that object.refis a weak reference to the same object.message = nullremoves the strong reference held bymessage.- The object is now reachable only through
ref, so it is eligible for weak-reference processing during GC.
Real World Use Cases
WeakReference use cases
- Listener registries: A publisher can avoid keeping a listener alive forever when the rest of the application has stopped using it.
- Metadata associated with external objects: Store optional data without making the external object remain in memory solely because of that metadata.
- Canonical mappings:
WeakHashMapuses weak keys, which can be useful when entries should vanish after their keys are no longer used elsewhere.
SoftReference use cases
- Recreatable, memory-sensitive values: For example, an expensive derived value that can be calculated again if it was cleared.
- Legacy cache-like behavior: Soft references have historically been used for caches, although they are often not ideal for modern application caches because eviction timing is controlled by the JVM and is unpredictable.
For an application cache with predictable limits, expiration, statistics, and eviction rules, use a dedicated cache library or an explicit bounded-cache design instead of relying on SoftReference.
Real Codebase Usage
In production code, weak references are commonly used to avoid accidental memory retention.
Check for null immediately
A reference can be cleared before you use it, so retrieve it once and check it:
UserProfile profile = profileReference.get();
if (profile == null) {
profile = loadProfile();
profileReference = new SoftReference<>(profile);
}
return profile;
Storing get() in a local variable gives the method a strong reference to the object while that local variable remains reachable.
Use WeakHashMap for weak keys
Instead of manually managing weak keys, use WeakHashMap when its semantics fit:
import java.util.Map;
import java.util.WeakHashMap;
Map<Object, String> labels = new WeakHashMap<>();
Object component = new Object();
labels.put(component, "sidebar");
component = null;
// After garbage collection, the entry may be removed.
Common Mistakes
Assuming get() never returns null
Broken code:
WeakReference<String> ref = new WeakReference<>(new String("data"));
System.out.println(ref.get().length());
If the weak reference has been cleared, this throws NullPointerException.
Use a local variable and validate it:
String value = ref.get();
if (value != null) {
System.out.println(value.length());
}
Expecting System.gc() to produce a reliable result
Broken test idea:
System.gc();
assert ref.get() == null;
The JVM is not required to run GC immediately, or to clear a particular reference at that exact point. Do not build application logic or deterministic tests around it.
Keeping an accidental strong reference
Object ();
WeakReference<Object> ref = <>(object);
Comparisons
| Reference type | Keeps object alive? | When can it be cleared? | Typical purpose |
|---|---|---|---|
| Strong reference | Yes | Only when no strong references remain | Normal program state |
SoftReference | Not permanently | At JVM discretion, commonly under memory pressure | Optional, recreatable values |
WeakReference | No | When the object is otherwise unreachable and GC processes weak references | Avoiding unintended retention |
PhantomReference | No | After finalization-related reachability processing; accessed through a queue | Advanced resource cleanup tracking |
WeakReference vs SoftReference
Cheat Sheet
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
SoftReference<Data> softRef = new SoftReference<>(data);
WeakReference<Data> weakRef = new WeakReference<>(data);
Data value = weakRef.get(); // Data or null
- Strong references keep objects alive.
WeakReferencedoes not keep its referent alive.SoftReferencemay retain its referent until the JVM needs memory.get()can returnnull; always handle that case.- Do not rely on
System.gc()for correctness or tests. - Remove all unintended strong references before expecting collection.
- Use weak references for optional associations and listener-like registries.
- Prefer explicit bounded or expiring caches over soft-reference caches when eviction must be predictable.
- Use
ReferenceQueueonly when you need cleanup notification after references are cleared.
FAQ
Is SoftReference stronger than WeakReference?
Yes. A softly reachable object is generally retained longer than a weakly reachable object, but neither is guaranteed to remain available.
When does Java clear a WeakReference?
After its referent is no longer strongly or softly reachable and the garbage collector processes weak references. The exact timing is not guaranteed.
When does Java clear a SoftReference?
The JVM decides. Soft references are commonly cleared in response to memory demand, but application code must not depend on a specific collection time.
Can WeakReference.get() return null immediately?
Yes. If there is no other strong reference to the object, GC may clear the weak reference before your next call to get().
Should I use SoftReference to implement a cache?
Usually not when the cache needs reliable behavior. Soft-reference eviction is JVM-controlled and difficult to predict. Prefer a cache with explicit size, expiration, and invalidation policies.
Does calling System.gc() guarantee that a weak or soft reference is cleared?
No. It is a request, not a guarantee, and the timing and outcome are JVM-dependent.
What is WeakHashMap used for?
Mini Project
Description
Build a small document-preview store that holds expensive-to-create previews with SoftReference. A preview may remain available for a later request, but the application can regenerate it when the JVM has cleared it. This demonstrates the essential rule for soft references: treat the value as optional and recover when get() returns null.
Goal
Create a preview store that returns a cached preview when available and regenerates it when it is missing or has been cleared.
Requirements
Use a Map<String, SoftReference<String>> to store previews by document ID.
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.