JVM Memory Management: Part 2

Mrinal Gupta
Nerd For Tech
Published in
4 min readOct 10, 2023

Java heavily relies on objects. As a developer, it is very important to understand how they are created, accessed, and manipulated. Referencing in Java refers to the mechanism that is used to access and manipulate objects. Let’s dive deeper!

Java Object Class

Reference Types

  • Strong References: It is the most common type of reference and is the default reference when we create and use the objects by using the “new” keyword or through any other means. A strong reference ensures that the object remains reachable as long as there is at least one strong reference pointing to it. In other words, as long as there’s a strong reference to an object, it won’t be eligible for garbage collection, and it will be retained in memory.
  • Weak Reference: A weak reference is a type of reference that allows an object to be garbage collected even if there are only weak references to it. Weak references are part of the Java platform’s memory management mechanism and are often used for scenarios where you want to retain an object in memory only as long as it is strongly referenced elsewhere. Weak references are created using the java.lang.ref.WeakReference class.

The object being referred to is wrapped by the instance of WeakReference class like below:

import java.lang.ref.WeakReference;


class Demonstration {
public static void main( String args[] ) {
String str = new String("Brand New String"); // This is a string reference
WeakReference<String> myString = new WeakReference<>(str);
str = null; // nulling the strong reference

// Try invoking the GC, but no guarantees it'll run
Runtime.getRuntime().gc();

if (myString.get() != null) {
System.out.println(myString.get());
} else {
System.out.println("String object has been cleared by the Garbage Collector.");
}
}
}

Run the above code to understand the behavior of weak references. Since the reference is set to null and the garbage collector has been called, else will get executed. Note, if we create the string using String literal, it will be stored in the Constant String Pool, not in the heap. In that case, if will be printed.

  • Soft References: A soft reference allows an object to be garbage collected if it is not strongly referenced and memory is needed. Soft references are created using the java.lang.ref.SoftReference class. Soft reference objects are cleared at the discretion of the garbage collector in response to memory demand. Soft references are most often used to implement memory-sensitive caches.

The difference between WeakReference and SoftReference is that the Garbage collector can collect an object if only weak references are pointing to it i.e., a weak reference is eagerly collected. On the other hand, objects with Soft Reference are only collected when the JVM absolutely needs memory.

  • Phantom Reference: A phantom reference is a type of reference that allows you to monitor an object’s finalization (cleanup) by the garbage collector, but it doesn’t provide direct access to the referenced object. Phantom references are part of the Java platform’s memory management mechanism and are created using the java.lang.ref.PhantomReference class.

Reference Queue

In Java, a reference queue (ReferenceQueue) is a data structure provided by the Java platform to work in conjunction with reference objects (such as weak, soft, and phantom references) for advanced memory management and resource cleanup. Reference queues are used to receive and manage references when they become eligible for collection or finalization by the garbage collector.

Run the below class in your IDE to understand the reference queue.

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

class Demonstration {
public static void main( String args[] ) {
// Declare an integer
Integer i = new Integer(420);

// Create a reference queue typed on Integer
ReferenceQueue<Integer> q = new ReferenceQueue<>();

// Create the weak reference and pass the queue as a param
WeakReference<Integer> wrappedInt = new WeakReference<>(i, q);

// Prints the wrapped integer.
System.out.println(wrappedInt.get().toString());


// Check if the queue has any item in it. It should return
// null since no GC has been performed
System.out.println(q.poll() == null ? "queue is empty" : "queue has an element");
}
}

The difference between Phantom references and other references is that the get() method of a phantom reference always returns null even before a GC has occurred. The other reference types return their referents with the get() method.

Phantom reference can be used to notify one when an object is out of scope to do resource cleanup. Remember that the object.finalize() method is not guaranteed to be called at the end of the life of an object, so if one needs to close files or free resources, one can rely on Phantom references.

This is all about references in Java. Now, you must have understood why we need to know about the object references and when they are available for garbage collection. This knowledge is sufficient to move to the final destination of our journey, Garbage Collection. See you in the next article for the same. Till then, happy coding!

--

--

Mrinal Gupta
Nerd For Tech

Software Developer on weekdays and A reading enthusiast on weekends. Beethoven’s silence and Chopin’s minute waltz intrigue me.