In this tutorial, we are going to learn about the most interesting topic in Java. That is the reference and its different types. Let’s see the basics of Reference types in Java and understand in a detailed manner.
Reference Types in Java
Whenever we talk about the reference types, it is better to have a basic idea about java garbage collector and how it works.
What is Garbage Collection?
Garbage collection is a sophisticated Java feature that takes care of automatic deallocation of objects that are not in use. The garbage collection mechanism reclaims memory from an object when there are no active references to that object. The types of references to an object also play an important role in garbage collection. This is because the decision to reclaim memory from the object heap is not just based on active references. It is also based on the type of references.
What are the different Reference Types?
In Java, there are four types of references, namely:
- Strong references
- Soft references
- Weak references
- Phantom references
To ensure that your program use memory efficiently, it is important to understand the different types of references and identify the most suitable reference types for your program.
A strong reference is one of the types of references that has the highest level of importance. Garbage collection does not select an object that has an active strong reference to it except when it uses cylindrical references.
Student stu1 = new Student();
This statement creates a strong reference to the newly created object ‘Student’. When the garbage collector runs, the object is selected for deallocation only if its strong reference is set to
nulland there are no other references to it.
stu1 = null;
This statement sets the strong reference stu1 to null. The object referred to by stu1 can now be collected by the garbage collector if there are no other references to it. Strong references are the most commonly used reference types in Java programs.
A soft reference is a reference type that creates a reference to an object that already has a strong reference to it. A Referent is the name of the object that this reference refers to. An object that has no references other than the soft references is reclaimed only if the memory is insufficient. You can create soft references by using the SoftReference class.
If you want to create a soft reference to an object, the first step is to create a strong reference to that object. The second step is to create a soft reference bypassing the strong reference as a parameter to the SoftReference constructor.
Student stu1 = new Student();
SoftReference<Student> softStu = new SoftReference<Student>(stu1);
In the first statement of the above example, we create a referent object allocate it to the heap memory. A strong reference, stu1, is also created for the new object. In the second statement, a soft reference, softStu, is created and allocated to memory. Through the parameter passed in the constructor, softStu obtains an internal reference to the referent object. The soft reference, softStu, also acts as a strong reference to the SoftReference object on the heap.
How Soft References Work?
Suppose the strong reference, stu1, in the previous example, is set to null and there is only one soft reference, softStu, to the referent Student object. If the garbage collector runs at this point, it can decide to reclaim memory from the Student object. However, this happens only if the JVM is about to encounter an OutOfMemory error.
If you want to prevent reclamation of an object, you can resurrect the object by obtaining a strong reference to it. As long as the object is present in memory, you can use the get() method on the soft reference to obtain a strong reference to the referent object.
Student resurrectedStu1 = softStu.get();
The usage of Soft references is for creating dynamic object pools. Suppose you are not aware of the size of an object pool and wish to allow it to grow dynamically while ensuring that the JVM efficiently reclaims memory from unused objects, you can go for soft references.
A weak reference comes into the picture when an object without any other references needs to be removed from the memory. If the garbage collector finds an object with only weak references, it marks that object for deallocation from the memory.
DBConnection stu = new Student();
WeakReference<DBConnection> weakStu = new WeakReference<DBConnection>(stu);
The above example creates a DBConnection object and a weak reference, weakStu, to the DBConnection object. When the garbage collector finds that weakStu is the only reference to the DBConnection object, it selects the DBConnection object for garbage collection.
How Weak References Work?
Weak references are most commonly used with a WeakHashMap. A WeakHashMap stores weak references as its keys so that the garbage collector can reclaim memory used by the keys that are not in use.
For example, you want to store user metadata for each database connection. You can use a WeakHashMap to store weak references of the database connection as keys and user metadata as values. When a database connection object has only weak references, the garbage collector reclaims memory from its keys and removes its entry from the WeakHashMap.
What are Reference Queues?
A reference queue is a queue that the JVM maintains to store references selected for garbage collection. Suppose the garbage collector marks an object with only weak references for garbage collection. If there is a reference queue in association with a weak reference, then the garbage collector adds the weak reference to that queue. This happens in situations, where, even though garbage collector marks an object, the JVM retains it in the queue so that the finalized method can be executed on it.
Student stu1 = new Student();
Student stu2 = new Student();
ReferenceQueue softStuQ = new ReferenceQueue();
ReferenceQueue weakStuQ = new ReferenceQueue();
SoftReference softR = new SoftReference (stu1, softStuQ);
WeakReference weakR = new WeakReference (stu2, weakStuQ);
This code uses two argument constructors of the SoftReference and WeakReference classes. This is to associate a soft reference and a weak reference to their respective reference queues.
A phantom reference is a reference type in association with a reference queue at the time of creation. Like soft and weak references, if a referent object has no other references other than phantom references, then the object is eligible for garbage collection. However, phantom references are different. Because, even if garbage collection selects the referent object, the reference queue adds the phantom references to it only after the execution of the finalize method. Because of this reason, phantom references cannot be resurrected and so on calling the get() method, it returns null.
Happy Learning 🙂