NOTE

7.17 References

Strong, soft, weak, and phantom references, examples, and WeakHashMap.

JavaCreated Updated 1 min readhistorical

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