Search code examples
javaoopjava-8garbage-collectionreference-type

Why Java has 4 different types of references?


Until today, I wasn't aware of the fact that Java has four main types of references.

  1. Strong Reference : Default reference type that Java uses.
  2. Weak Reference : If an object has a weak reference then GC reclaims this object’s memory in next run even though there is enough memory.
  3. Soft Reference : If an object has a soft reference, then GC reclaims this object’s memory only when it needs some memory badly.
  4. Phantom Reference : If an object has a phantom reference, then it's eligible for garbage collection. But, before GC, JVM puts the objects which are supposed to be garbage collected in a queue called reference queue.

I understood the basic concept and I wrote a small program to understand how each of the reference types work.

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

class User 
{ 
    public User info() 
    { 
        System.out.println("Info method invoked from User class");
        return null;
    }   
} 

public class ReferencesExample 
{ 
    public static void main(String[] args) 
    { 
        //Strong Reference
        User userRefObj = new User(); 
        System.out.println("1 :" + userRefObj.info());

        // Weak Reference
        WeakReference<User> weakref = new WeakReference<User>(userRefObj.info());  
        System.out.println("2 : " + weakref);

        // Soft Reference    
        SoftReference<User> softref = new SoftReference<User>(userRefObj.info());  
        System.out.println("3 : " + softref);

        // Phantom Reference 
        ReferenceQueue<User> refQueueObj = new ReferenceQueue<User>(); 
        PhantomReference<User> phantomRef = new PhantomReference<User>(userRefObj.info(),refQueueObj); 
        System.out.println("4 : " + phantomRef);     
       
    } 
}

Output :

1 :null
Info method invoked from User class
Info method invoked from User class
2 : java.lang.ref.WeakReference@15db9742
Info method invoked from User class
3 : java.lang.ref.SoftReference@6d06d69c
Info method invoked from User class
4 : java.lang.ref.PhantomReference@7852e922

Doubt : How do we decide which reference type to use and where exactly to use in a real world scenario ?


Solution

  • It's a complicated answer to provide, especially the "real world" portion. These special references are a (very) sharp tool to use, it should only be touched rarely and with a very good understanding. Your first misconception is that only Phantom References use a queue (called ReferenceQueue). In fact, they all use a queue. PhantomReference was a bit of a "weirdo" among these all, mainly because the specification around it has changed from java-8 to java-9. You can read this answer to get some details (the reasons for keeping the instance alive in java-8 is unknown to this time).

    Then the common misconception you get is that "next run", for more details you can take a look here. The notion here of the "second", or "next" is a bit tricky; but the point is that this is non-deterministic.

    Providing "real world" examples, comes a bit tricky too. That happens because you rarely use these references directly, they usually come pre-packaged in utilities. For one example, you can take a look of how WeakHashMap works (that directly uses the WeakReference and ReferenceQueue under the hood), or event this answer. guava with its CacheBuilder used to offer some functionality dealing with SoftReferences(but not anymore), caffeine still does though.

    PhantomReferences are used internally for Cleaner API (since java-9). here is an example that shows its general usage. Without PhantomReferences, this would not really be possible (at least not that "easy").


    To that extent, we use WeakHashMap in production (so do we use Cleaner API, but much less). If you really want to learn about them, you need to understand how a garbage collector works (like, really works), then read their official documentation and try (and ask) multiple things.