Weak References in Java

1. Overview

In this article, we’ll have a look at the concept of a weak reference – in the Java language.

We’re going to explain what these are, what they’re used for, and how to work with them properly.

2. Weak References

A weakly referenced object is cleared by the Garbage Collector when it’s weakly reachable.

Weak reachability means that an object has neither strong nor soft references pointing to it. The object can be reached only by traversing a weak reference.

First off, the Garbage Collector clears a weak reference, so the referent is no longer accessible. Then the reference is placed in a reference queue (if any associated exists) where we can obtain it from.

At the same time, formerly weakly-reachable objects are going to be finalized.

2.1. Weak vs Soft References

Sometimes the difference between weak and soft references is unclear. Soft references are basically a big LRU cache. That is, we use soft references when the referent has a good chance of being reused in the near future.

Since a soft reference acts as a cache, it may continue to be reachable even if the referent itself is not. As a matter of fact, a soft reference is eligible for collection if and only if:

  • The referent is not strongly reachable
  • The soft reference is not being accessed recently

So a soft reference may be available for minutes or even hours after the referent becomes unreachable. On the other hand, a weak reference will be available only for as long as its referent is still around.

3. Use Cases

As stated by Java documentation, weak references are most often used to implement canonicalizing mappings. A mapping is called canonicalized if it holds only one instance of a particular value. Rather than creating a new object, it looks up the existing one in the mapping and uses it.

Of course, the most known use of these references is the WeakHashMap class. It’s the implementation of the Map interface where every key is stored as a weak reference to the given key. When the Garbage Collector removes a key, the entity associated with this key is deleted as well.

For more information, check out our guide to WeakHashMap.

Another area where they can be used is the Lapsed Listener problem.

A publisher (or a subject) holds strong references to all subscribers (or listeners) to notify them about events that happened. The problem arises when a listener can’t successfully unsubscribe from a publisher.

Therefore, a listener can’t be garbage collected since a strong reference to it’s still available to a publisher. Consequently, memory leaks may happen.

The solution to the problem can be a subject holding a weak reference to an observer allowing the former to be garbage collected without the need to be unsubscribed (note that this isn’t a complete solution, and it introduces some other issues which aren’t covered here).

4. Working With Weak References

Weak references are represented by the java.lang.ref.WeakReference class. We can initialize it by passing a referent as a parameter. Optionally, we can provide a java.lang.ref.ReferenceQueue:

Object referent = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();

WeakReference weakReference1 = new WeakReference<>(referent);
WeakReference weakReference2 = new WeakReference<>(referent, referenceQueue);

The referent of a reference can be fetched by the get method, and removed manually using the clear method:

Object referent2 = weakReference1.get();
weakReference1.clear();

The pattern for safe working with this kind of references is the same as with soft references:

Object referent3 = weakReference2.get();
if (referent3 != null) {
    // GC hasn't removed the instance yet
} else {
    // GC has cleared the instance
}

5. Conclusion

In this quick tutorial, we had a look at the low-level concept of a weak reference in Java – and focused on the most common scenarios to use these.

Related posts:

REST Web service: Basic Authentication trong Jersey 2.x
XML Serialization and Deserialization with Jackson
Java Program to Check Whether Topological Sorting can be Performed in a Graph
Base64 encoding và decoding trong Java 8
File Upload with Spring MVC
Convert String to int or Integer in Java
Intro to Spring Boot Starters
Các nguyên lý thiết kế hướng đối tượng – SOLID
Java Program to Implement Depth-limited Search
“Stream has already been operated upon or closed” Exception in Java
Spring Boot - Apache Kafka
Java Program to Find SSSP (Single Source Shortest Path) in DAG (Directed Acyclic Graphs)
Ways to Iterate Over a List in Java
A Custom Media Type for a Spring REST API
Map Interface trong java
Java Program to Implement Quick sort
Overview of the java.util.concurrent
Xử lý ngoại lệ trong Java (Exception Handling)
Documenting a Spring REST API Using OpenAPI 3.0
A Guide to Java HashMap
Guide to the Synchronized Keyword in Java
Java Program to Implement Hash Tables Chaining with Binary Trees
Spring Boot Tutorial – Bootstrap a Simple Application
Generate Spring Boot REST Client with Swagger
Java Program to Implement the Edmond’s Algorithm for Maximum Cardinality Matching
REST Web service: Upload và Download file với Jersey 2.x
Immutable Map Implementations in Java
Rate Limiting in Spring Cloud Netflix Zuul
A Quick Guide to Spring Cloud Consul
Java Program to Implement Jarvis Algorithm
Inheritance and Composition (Is-a vs Has-a relationship) in Java
Allow user:password in URL