Contrast SoftReference and WeakReference: how do their clearing policies differ, and which fits a memory-sensitive cache versus a WeakHashMap-style side table?
answer
- Weak = clear at next GC; Soft = clear only under memory pressure
- Same Reference superclass, same get(); difference is reachability strength
- Strong > soft > weak > phantom
- Soft → memory-sensitive cache; Weak → WeakHashMap keys / side tables
- Wrong choice = leak (soft side table) or instant eviction (weak cache)
basics
~20 sA weak reference is thrown away as soon as the next garbage collection runs once nothing else points to the object. A soft reference is kept longer — the collector only clears it when memory is running low. So soft is for caches you want to keep; weak is for cleanup that should happen quickly.
solid answer
~50 sBoth SoftReference and WeakReference let the GC reclaim their referent once no strong reference remains, and both are subclasses of java.lang.ref.Reference with the same get() API. The difference is *timing*. A weakly-reachable object is reclaimed eagerly: the next GC that notices it clears the reference, regardless of free memory. A softly-reachable object is reclaimed lazily: the GC retains it while memory is comfortable and clears it only under memory pressure, before an OutOfMemoryError, roughly LRU-ordered. Therefore a SoftReference fits a memory-sensitive cache — you want entries to live as long as the heap allows but be sacrificed rather than OOM. A WeakReference fits a side table or canonicalizing map (the basis of WeakHashMap) where an entry should disappear promptly once its key is no longer used elsewhere, so the map never pins memory. Picking soft for a side table would leak; picking weak for a cache would evict almost immediately and waste the work.
go deeper
Knows weak is cleared quickly (next GC) and soft is kept longer (until low memory), and that soft suits caches.
Can state both share Reference/get(), explain reachability-strength ordering, and correctly map soft→cache, weak→WeakHashMap, justifying why the swapped choice misbehaves.
Explains HotSpot's SoftRefLRUPolicyMSPerMB heuristic, the LRU-ish ordering, the all-at-once clearing cliff, and why a real bounded cache usually beats soft references.
Weighs caching strategy at system scale: soft-ref caches interact with heap sizing and GC pauses, can hide leaks, and clear unpredictably; advises explicit eviction policies and observability over relying on GC-driven clearing.
## Shared machinery Both `SoftReference<T>` and `WeakReference<T>` extend `java.lang.ref.Reference<T>`. You construct each around a **referent** (the wrapped object), optionally registering a **ReferenceQueue** that the GC enqueues the reference onto after it clears it. You read the referent with `get()`, which returns the object or `null` once cleared. The structural difference is purely the **reachability strength** the JVM assigns, which dictates *when* the GC is allowed to clear the referent. ## Reachability strengths The JVM defines a strength ordering, strongest to weakest: **strongly reachable** > **softly reachable** > **weakly reachable** > **phantom reachable**. An object's effective strength is the *strongest* reference that can reach it. So if an object is reachable both strongly (an ordinary variable) and via a SoftReference, it is strongly reachable and never collected. Only when *all* stronger paths are gone does the softer one decide its fate. - **Softly reachable**: reachable through at least one SoftReference but no stronger path. The GC *may* clear such references but is encouraged to keep them until memory is low, clearing before an OutOfMemoryError. - **Weakly reachable**: reachable through at least one WeakReference but no stronger path. The GC clears these *as soon as it determines weak reachability* — at the next collection cycle — with no regard to free memory. ## The timing contrast, concretely Imagine you cache a large parsed document. If you hold it via a **WeakReference**, the moment your code stops strongly referencing it, the next minor GC can throw it away — even though you have gigabytes free and intended to reuse it. That defeats the cache. If you hold it via a **SoftReference**, the JVM keeps it through many GCs while memory is comfortable, and only sacrifices it when the heap is genuinely tight. That is the caching behavior you want. Conversely, imagine a **side table** that associates metadata with objects you don't own — e.g. mapping `key -> extra info`. You want an entry to vanish the instant the key is no longer used elsewhere, so the table never keeps keys alive. That is exactly **WeakHashMap**, whose keys are held by WeakReferences: when a key becomes weakly reachable, the next GC clears it and the map drops the stale entry. Using soft references here would *retain* keys until memory pressure — a memory leak relative to the intent. ## HotSpot's soft-reference heuristic Weak clearing is simple (next GC). Soft clearing uses a policy: HotSpot keeps a soft referent for about `-XX:SoftRefLRUPolicyMSPerMB` milliseconds *per megabyte of free heap* since the referent was last accessed (default 1000). More free memory → longer retention; under pressure, the least-recently-used soft referents clear first. This makes soft references behave like an *adaptive, GC-managed LRU cache* — imprecise, but free. ## Choosing - **Memory-sensitive cache** (recomputable/reloadable data you'd keep if you could): **SoftReference**, or better, a real cache (Caffeine) with bounds. - **Canonicalizing map / metadata side table / listener registry that must not pin its keys**: **WeakReference** / **WeakHashMap**. - A common mistake is reaching for soft references as a cache and being surprised when, under load, *all* entries clear simultaneously (a latency cliff) — a bounded cache avoids that.
- Why does WeakHashMap use weak references rather than soft references for its keys?Because the intent is that an entry disappears as soon as its key is no longer used anywhere else, so the map never keeps keys alive. Weak references give that prompt removal at the next GC. Soft references would retain keys until memory pressure, turning the map into an unintended cache and a relative memory leak.
- What happens to a SoftReference-based cache under sudden memory pressure?The GC can clear many or all soft referents in a single collection to avoid an OutOfMemoryError, producing a cache-clearing 'cliff': a burst of cache misses and recomputation right when the system is already stressed. A bounded cache with explicit eviction avoids this all-or-nothing behavior.
saying these in an interview costs you the question
- Saying weak and soft clear at the same time — weak is eager, soft is under pressure
- Claiming WeakHashMap uses soft references for its keys (it uses weak references)
- Recommending WeakReference for a cache — entries would evict almost immediately
- Asserting soft references guarantee retention until OOM (the GC may clear at its discretion earlier)