References
About
In Java, references determine how an object is accessed and managed in memory, especially with regard to garbage collection (GC). Java provides different types of references strong, weak, soft, and phantom each with varying implications on memory management.
1. Strong Reference
About
A strong reference is the default reference type in Java. It ensures that the referenced object remains in memory and is not eligible for garbage collection as long as the reference exists.
Characteristics
A strong reference prevents the garbage collector from reclaiming the memory of the referenced object.
The object will only be garbage collected if the reference is explicitly set to
null
or goes out of scope.Most objects we create in Java are strong references by default.
Example of Strong Reference
public class StrongReferenceExample {
public static void main(String[] args) {
// The strongRef variable is a strong reference to the String object.
String strongRef = new String("Hello, World!");
// This object cannot be garbage collected until `strongRef` is set to null
System.out.println(strongRef); // Output: Hello, World!
// Nullify the reference
strongRef = null;
// Now the object is eligible for garbage collection
}
}
When to Use
When we want to ensure the object is always accessible and not accidentally reclaimed by the garbage collector.
For most regular object references.
2. Weak Reference
About
A weak reference allows the garbage collector to reclaim the referenced object if there are no other strong references to it. Weak references are used when we want to allow the object to be garbage collected while still having a reference to it.
Characteristics
A weak reference does not prevent its referent (the object it refers to) from being garbage collected.
Used in conjunction with
java.lang.ref.WeakReference
class.Often used for memory-sensitive caching and maps like
WeakHashMap
.
Example of Weak Reference
import java.lang.ref.WeakReference;
public class WeakReferenceExample {
public static void main(String[] args) {
// Create a strong reference
String strongRef = new String("WeakReference Example");
// Create a weak reference to the object
WeakReference<String> weakRef = new WeakReference<>(strongRef);
// Print the value via weak reference
System.out.println("Before GC: " + weakRef.get()); // Output: WeakReference Example
// Nullify the strong reference
strongRef = null;
// Request garbage collection
System.gc();
// Allow some time for GC to run
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Check if the object was garbage collected
System.out.println("After GC: " + weakRef.get()); // Output: null (if GC collected the object)
}
}
When to Use
Caches: Weak references are used in
WeakHashMap
to allow keys to be garbage collected when no longer in use.Listeners: Weak references are used for listeners or observers in event-driven systems to avoid memory leaks.
What Happens in the Examples?
Strong Reference Example:
String strongRef = new String("Hello, World!");
The
strongRef
variable is a strong reference to theString
object.As long as
strongRef
exists and is not set tonull
, the garbage collector cannot reclaim the object, even if memory is low.
If we set strongRef = null
, there are no references to the object, and it becomes eligible for garbage collection.
Weak Reference Example:
String strongRef = new String("WeakReference Example");
WeakReference<String> weakRef = new WeakReference<>(strongRef);
strongRef
is a strong reference to theString
object, andweakRef
is a weak reference to the same object.As long as
strongRef
exists, the object is not eligible for garbage collection, because the strong reference keeps it alive.When we set
strongRef = null
, only the weak reference remains. This makes the object eligible for garbage collection, even ifweakRef
still points to it.
3. Soft Reference
About
A soft reference is a reference that allows the garbage collector to reclaim the referenced object only when the JVM runs out of memory. It is more lenient than a weak reference and is often used for implementing memory-sensitive caches.
Characteristics
The garbage collector clears a soft reference only when memory is low, making it useful for caching.
If a soft reference is not reclaimed, you can still access the object.
Implemented using the
java.lang.ref.SoftReference
class.Provides a balance between strong and weak references: the object remains accessible unless the JVM is under memory pressure.
Example of Soft Reference
import java.lang.ref.SoftReference;
public class SoftReferenceExample {
public static void main(String[] args) {
// Create a strong reference
String strongRef = new String("SoftReference Example");
// Create a soft reference to the object
SoftReference<String> softRef = new SoftReference<>(strongRef);
// Print the value via soft reference
System.out.println("Before GC: " + softRef.get()); // Output: SoftReference Example
// Nullify the strong reference
strongRef = null;
// Request garbage collection
System.gc();
// Allow some time for GC to run
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Check if the object was garbage collected
System.out.println("After GC: " + softRef.get()); // Likely still accessible unless memory is low
}
}
When to Use:
Caching: Soft references are often used for memory-sensitive caching. For example, in an image cache: Images can be held in memory as long as the JVM has enough memory. If memory runs low, the cache will release them.
Phantom Reference
About
A phantom reference is the weakest type of reference in Java. Unlike weak or soft references, a phantom reference does not allow access to the referenced object at any point. Phantom references are typically used in conjunction with a ReferenceQueue
to track the lifecycle of objects and perform cleanup operations after the object has been finalized but before its memory is reclaimed by the garbage collector.
Characteristics
Accessing the referent through
PhantomReference.get()
always returnsnull
.The primary use is for cleanup actions, as the reference is enqueued in a
ReferenceQueue
after the object is finalized but before memory is reclaimed.Implemented using
java.lang.ref.PhantomReference
.Requires a
ReferenceQueue
to be useful.Used for advanced memory management tasks, such as ensuring certain cleanup tasks are performed before memory is freed.
Example of Phantom Reference
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
public class PhantomReferenceExample {
public static void main(String[] args) {
// Create a strong reference
String strongRef = new String("PhantomReference Example");
// Create a reference queue
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
// Create a phantom reference to the object
PhantomReference<String> phantomRef = new PhantomReference<>(strongRef, referenceQueue);
System.out.println(phantomRef.get()); // Always returns null
// Nullify the strong reference
strongRef = null;
// Request garbage collection
System.gc();
// Allow some time for GC to run
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Check if the object was enqueued
Reference<? extends String> refFromQueue = referenceQueue.poll();
if (refFromQueue != null) {
System.out.println("The phantom-referenced object has been enqueued for cleanup.");
} else {
System.out.println("The object is not yet garbage collected.");
}
}
}
Why Are Phantom References Useful?
Phantom references solve problems that weak references cannot handle:
Finalization Tracking:
Weak references cannot detect when an object has been finalized; they only indicate when the object is garbage collected.
Phantom references ensure that we can track an object's finalization and take appropriate actions before memory is reclaimed.
Post-Finalization Cleanup:
Phantom references are used to clean up resources (e.g., close file descriptors, release native memory) associated with an object after it has been finalized.
Weak references do not provide such capabilities.
When is an Object Finalized?
An object is considered finalized after the following steps occur:
Object Becomes Unreachable:
The object is no longer accessible through any strong references in your program.
The garbage collector identifies it as eligible for garbage collection.
finalize()
Method is Called:The garbage collector invokes the
finalize()
method on the object before reclaiming its memory.If the object overrides the
finalize()
method, it can perform cleanup operations.
Object Memory is Reclaimed:
After
finalize()
finishes execution, the object's memory is freed, and the object is destroyed (unless it resurrects itself, explained below).
Comparison of all four reference types
Aspect
Strong Reference
Soft Reference
Weak Reference
Phantom Reference
Definition
Default type of reference in Java; ensures the object remains in memory.
Prevents object collection unless JVM memory is low.
Allows object collection as soon as no strong references exist.
Tracks object lifecycle post-finalization but does not allow access to the object.
Garbage Collection
Object is never garbage collected unless reference is explicitly cleared or nullified.
Object is garbage collected only if memory is low.
Object is garbage collected immediately after no strong references exist.
Object is collected after finalization, just before memory is reclaimed.
Access to Object
Object is always accessible until explicitly cleared.
Accessible via get()
until the object is collected.
Accessible via get()
until the object is collected.
Always returns null
when accessed via get()
.
Strength of Reference
Strongest (default behavior in Java).
Weaker than strong references but stronger than weak references.
Weaker than both strong and soft references.
Weakest of all reference types.
Reference Class
No special class required (default reference).
java.lang.ref.SoftReference
.
java.lang.ref.WeakReference
.
java.lang.ref.PhantomReference
.
ReferenceQueue Usage
Not applicable.
Optional (to monitor when object is collected).
Optional (to monitor when object is collected).
Mandatory (used to track objects for cleanup before memory reclamation).
Use Case
General-purpose programming where the object must persist in memory.
Caching, where objects can be retained until memory is needed elsewhere.
Mapping objects (e.g., WeakHashMap
), listeners, and avoiding memory leaks.
Post-finalization cleanup, resource deallocation, and advanced resource tracking.
Example Collection
Never garbage collected until explicitly cleared.
Collected only under memory pressure.
Collected as soon as no strong references exist.
Collected after finalization and queued for cleanup.
Last updated