memory management
advancedMemory Leaks & Reference Types
Recognize how unintended references prevent GC, and use Strong / Soft / Weak / Phantom references to control object lifetime.
A memory leak in a garbage-collected language sounds like a contradiction, but it happens whenever an object is still reachable from a GC root even though the program will never use it again. The collector cannot tell "unused" from "unreachable" — it only reclaims the latter — so an accidental reference is enough to pin an object in memory forever, and many such objects accumulate into an OutOfMemoryError.
Strong = a leash you're holding. Soft = a leash on a hook (cut only if the room is full). Weak = a sticky note (gone with the next cleaning). Phantom = a notification when the object is being thrown out.
Key Concepts
1
The classic culprits are all about lingering references. A static collection that you add to but never remove from grows without bound. A HashMap keyed by objects whose equals/hashCode you've defined poorly, or simply never cleaned, retains entries indefinitely. Listeners and callbacks registered with a long-lived publisher but never unregistered keep their owners alive (the lapsed-listener problem). Unclosed resources and ThreadLocals on pooled threads are other frequent offenders. To control object lifetime deliberately, Java offers a hierarchy of reference strengths: a normal strong reference prevents collection; a SoftReference lets the object survive until memory runs low (useful for caches); a WeakReference lets the object be collected as soon as nothing strongly references it (the basis of WeakHashMap and listener registries that auto-clean); and a PhantomReference with a ReferenceQueue provides a hook to run cleanup after an object is collected, replacing the unreliable finalize().
HashMapequalshashCodeThreadLocalSoftReference
2
In practice, you find these leaks with a profiler or by capturing a heap dump and looking for the dominant retained set and the reference chain holding it to a root. The fix is almost always to remove the reference at the right time — clear the collection entry, unregister the listener, close the resource in a finally or try-with-resources — or to switch to a weak/soft reference when you genuinely want the cache or registry to release its contents automatically.
finallytry-with-resources