NOTE
7.17 References
Strong, soft, weak, and phantom references, examples, and WeakHashMap.
This is a historical learning note and may contain outdated or incomplete understanding.
1. Strong, Soft, Weak, and Phantom References

1.1. Strong
The most common kind of reference. If an object has a strong reference, it will not be reclaimed.
- Example
Object object = new Object();
System.out.println(object);//java.lang.Object@1b6d3586
System.gc();
System.out.println(object);//java.lang.Object@1b6d3586
1.2. Soft
It is not reclaimed when memory is sufficient, but may be reclaimed when memory is insufficient.
Implemented using SoftReference, generally used for caching.
- Example
// When memory is sufficient.
public static void softRefMemoryEnough()
{
Object obj1 = new Object();
SoftReference<Object> softReference = new SoftReference<>(obj1);
System.out.println(obj1);
System.out.println(softReference.get());
obj1 = null;
System.gc();//Trigger GC.
System.out.println(obj1);
System.out.println(softReference.get());//The soft reference is not reclaimed.
}
// When memory is insufficient.
// -Xms10m -Xmx10m -XX:+PrintGCDetails
public static void softRefMemoryNotEnough()
{
Object obj1 = new Object();
SoftReference<Object> softReference = new SoftReference<>(obj1);
System.out.println(obj1);
System.out.println(softReference.get());
obj1 = null;
try
{
byte[] bytes = new byte[1024 * 1024 * 30];
}catch (Exception e)
{
e.printStackTrace();
}
finally
{
System.out.println(obj1);
System.out.println(softReference.get());//The soft reference is reclaimed.
}
}
1.3. Weak
Regardless of whether memory is sufficient, once GC occurs it will be reclaimed.
public static void weakRefMemoryEnough()
{
Object obj1 = new Object();
WeakReference<Object> softReference = new WeakReference<>(obj1);
System.out.println(obj1);
System.out.println(softReference.get());
obj1 = null;
System.gc();
System.out.println(obj1);
System.out.println(softReference.get());
}
1.4. Phantom
Used to monitor GC reclamation; it has little direct use.
A phantom reference must be used together with a reference queue (ReferenceQueue). When the garbage collector prepares to reclaim an object, if it finds that the object still has a phantom reference, it adds the phantom reference to the associated reference queue before reclaiming the object’s memory.
public static void xuTest() throws InterruptedException
{
Object object = new Object();
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomReference = new PhantomReference<>(object, queue);
System.out.println(object);
System.out.println(phantomReference.get());
System.out.println(queue.poll());
System.out.println("-================");
object = null;
System.gc();
Thread.sleep(50);
System.out.println(object);
System.out.println(phantomReference.get());
System.out.println(queue.poll());
}
1.4.1. Usage Scenario
- WeakHashMap
public static void hashMapTest()
{
HashMap<Integer, String> map = new HashMap<>();
Integer key = new Integer(1);
map.put(key, "aaaaaaaaaa");
System.out.println(map);
key = null;
System.gc();
System.out.println(map);
}
public static void weakHashMapTest()
{
WeakHashMap<Integer, String> map = new WeakHashMap<>();
Integer key = new Integer(1);
map.put(key, "aaaaaaaaaa");
System.out.println(map);
key = null;
System.gc();
System.out.println(map);
}
Discussion
Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub