- Manage Email Subscriptions
- How to Post to DZone
- Article Submission Guidelines
- Manage My Drafts
Enterprise AI in 2024 : Share your insights into ChatGPT, generative AI, MLOps , and more (+enter the raffle!) for DZone's March Trend Report.
Getting Started With Large Language Models : A guide for both novices and seasoned practitioners to unlock the power of language models.
Managing API integrations : Assess your use case and needs — plus learn patterns for the design, build, and maintenance of your integrations.
Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.
- Duplicate Objects in Java: Not Just Strings
- Java: How Object Reuse Can Reduce Latency and Improve Performance
- All You Need To Know About Garbage Collection in Java
- Java Object Size: Estimating, Measuring, and Verifying via Profiling
- Top Software Development Trends To Look For in 2024
- How Artificial Intelligence (AI) Is Transforming the Mortgage Industry
- What Is JSON Schema?
- Protecting Privacy in the Age of Edge AI: The Role of Homomorphic Encryption
Weak, Soft, and Phantom References in Java (and Why They Matter)
This breakdown of weak, soft, and phantom references explains how they impact gc and memory allocation as well as some ideal use cases..
Join the DZone community and get the full member experience.
Allocation problem at Sunset restaurant in Crete
Almost every Java programmer knows there are Soft and Weak references, but usually, they are not fully understood. Phantom ones are even less well-known.
I think this is a bit of a shame because they are not complex to understand (compared to Locks, for example), and they can be really useful to know if you have memory problems with your application.
So, I have prepared a tiny GitHub project to show how to use them. It is also quite interesting how the different garbage collectors are treating them, but that will be the topic for my next post.
Before analyzing the code, let’s consider why we need memory references at all.
One common problem of all computer languages that allow for dynamic memory allocation is finding a way to “collect” the memory after is not used anymore.
It is a bit like in a restaurant. In the beginning, you can accommodate customers with empty tables, but when you don’t have empty tables anymore, you need to check if some of the already-allocated tables have got free in the meanwhile.
Some languages, like C, leave the responsibility to users: You have the memory and now it is your responsibility to free it. It’s a bit like in fast food, where you are (in theory) supposed to clean up your table after the meal.
This is very efficient… if everybody behaves correctly. But if some customers forget to clean up, it will easily become a problem. Same with memory: It’s very easy to forget to free an area of memory.
So Garbage Collectors (GC from here on) come to help. Some languages, namely Java, use a special algorithm to collect all the memory that is not used. That is very nice of them and very convenient for programmers. You may be forgiven if you think that GC is a relatively recent technique.
Garbage collection was invented by John McCarthy around 1959 to simplify manual memory management in Lisp.
Modern GCs are very sophisticated programs, and they use several combined techniques to quickly identify memory that can be reused. For the moment, let’s assume Java GC works flawlessly and that it will free all objects that are not reachable anymore.
That introduces a new problem: What if we want to keep a reference to an object, but we don’t want to prevent GC from freeing it if there is no other reference? It’s a bit like sitting a while at a table at a restaurant after having finished, but also being ready to leave if a new customer needs the table.
You may wonder why would I need such a thing. Actually, there are a few use cases. Let’s introduce our protagonists from the Java documentation:
SoftReference : 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. All soft references to softly reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError .
WeakReference : Weak reference objects do not prevent their referents from being made finalizable, finalized, and then reclaimed. Weak references are most often used to implement canonicalizing mappings. (Here, Canonicalizing mappings means mapping only reachable object instances.)
PhantomReference : Phantom reference objects are enqueued after the collector determines that their referents may otherwise be reclaimed. Phantom references are most often used for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism. Unlike soft and weak references, phantom references are not automatically cleared by the garbage collector as they are enqueued. An object that is reachable via phantom references will remain so until all such references are cleared or themselves become unreachable.
So in brief: Soft references try to keep the reference. Weak references don’t try to keep the reference. Phantom references don’t free the reference until cleared.
To reuse (and stretch) our restaurant metaphor one last time: A SoftReference is like a customer that says, "I’ll leave my table only when there are no other tables available." A WeakReference is like someone ready to leave as soon as a new customer arrives. A PhantomReference is like someone ready to leave as soon as a new customer arrives, but actually not leaving until the manager gives them permission.
Now let’s go back to the code .
The small program runs from the command line and does a few, simple things:
- Allocate 500,000 1KB blocks in a linked list,
- Reference them using one of the 3 reference types.
- De-reference half of them,
- Remove unused references,
- Repeat all of the above 100 times and exit.
To make things difficult for the GC, it removes alternate elements from the linked list so that the list is always composed of elements of a different “age”. Which is important for how GC works, as we will see in the next post.
As you can see, it is very easy to create a reference to our object (curr in this case). All reference types take the referenced object in the constructor and, optionally, a queue as a parameter.
We can always reach the referenced object with the method get() . In the case of Weak and Soft, get will return the actual object if still active — that is, if it is reachable by other objects. In case the object has been collected, get() will return null.
This opens a possible problem if someone manages to “resurrect” the object using the reference get() during the finalization. For this reason, Phantom always returns null in the get() regardless of whether the object is still active. In this way, we can pass a PhantomReference to another object without risking that it will store a new, hard reference to it.
The other parameter in the constructor is the ReferenceQueue . To understand why is important, we have to consider how we know when the referenced object is finalized.
For Soft and Weak references, we can check the get() method, but it would be very time consuming if we have a big list of references. Moreover, for Phantom references, we cannot use it at all.
For this reason, if we pass a queue in the constructor of the reference, we will get a notification when the referenced object expires. In my simple example, I poll the queue after the deallocation:
If queue.poll() returns null, then the queue is empty. A less naive approach is to create a separate thread and call queue.remove() , which will block until there is something to remove.
Just remember that whilst Weak and Soft references are put in the queue after the object is finalized, Phantom references are put in the queue before . If for any reason you don’t poll the queue, the actual objects referenced by Phantom will not be finalized, and you can incur an OutOfMemory error.
Well, so now that we understand memory references better, what can we use them for?
The Java documentation already suggests some uses for the references.
SoftReferences can be used to implement a cache that can grow without risking an application crash. To do this, you need to implement a Map interface in which values are stored, wrapped inside a SoftReference. SoftReferences will keep the objects alive until there is memory available on the heap, but it will discard them before an OutOfMemoryError.
If you are interested, there is an example in Guava to study. You need to keep in mind that filling almost all your memory can slow down your program so much that a cache hardly matters. It’s easy to verify this just by running the program and uncommenting the line that creates the SoftReference.
WeakReferences can be used, for example, to store some information related to an object until the object gets finalized. To do this, you can implement a Map in which the keys are wrapped in a WeakReference. As soon as GC reclaims the key object, you can remove the value as well.
Of course, it can also be done using some notification mechanism, but using GC will be more robust and efficient. As an example, you can look at java.util.WeakHashMap, but it is not thread-safe.
PhantomReferences can be used to notify you when some object is out of scope to do some 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 you need to close files or free resources, you can rely on Phantom. Since Phantom doesn't have a link to the actual object, a typical pattern is to derive your own Reference type from Phantom and add some info useful for the final freeing, for example filename.
@simonebordet suggested another use for Phantom (or Weak) references: To verify memory leaks. You can look at the Jetty LeakDetector class as an example.
Playing around with this small program, I also verified that WeakReferences are sensibly faster than ShadowReferences. In a project I am working on, I added a WeakReference to some critical resources for each request, and then I added monitor info to verify they are actually freed in a reasonable time after the request expires.
I learned a lot writing this, and I hope this post can be useful to other people as well. The next blog post will continue the analysis of memory allocation and performance, comparing Java CMS and G1 Garbage Collectors.
Published at DZone with permission of Uberto Barbini , DZone MVB . See the original article here.
Opinions expressed by DZone contributors are their own.
- About DZone
- Send feedback
- Advertise with DZone
CONTRIBUTE ON DZONE
- Become a Contributor
- Core Program
- Visit the Writers' Zone
- Terms of Service
- 3343 Perimeter Hill Drive
- Nashville, TN 37211
- [email protected]
Let's be friends:
Reference types in Java : Strong, Soft, weak, Phantom
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.
Example: 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 null and there are no other references to it.
Example: 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.
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.
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.
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 🙂
- Java WeakHashMap class Example
- Java Heap and Garbage Collection
- Java variable types Example
- Technical Features of Java Programming
- What is Java Constructor and Types of Constructors
- Comparable in Java
- Advantages of Java Programming
- Different types of Object States in Hibernate
- What are different Python Data Types
- Collection Framework & Collection Interfaces in Java
- Java – Types of Polymorphism and Advantages
- What is Java Arrays and how it works ?
- Java 8 Getting Min and Max values from a Stream
- Types of Spring Bean Scopes Example
- Java Static Variable Method Block Class Example
Share a word.
About the author: chandrashekhar.
- 90% Refund @Courses
- Java Arrays
- Java Strings
- Java Collection
- Java 8 Tutorial
- Java Multithreading
- Java Exception Handling
- Java Programs
- Java Project
- Java Collections Interview
- Java Interview Questions
- Spring Boot
- Explore Our Geeks Community
- Static methods vs Instance methods in Java
- Java | How to create your own Helper Class?
- Valid variants of main() in Java
- Static Blocks in Java
- Using predefined class name as Class or Variable name in Java
- Singleton Method Design Pattern in Java
- Numbers in Java (With 0 Prefix and with Strings)
- Why to Override equals(Object) and hashCode() method ?
- String Handling with Apache Commons' StringUtils Class in Java
- C/C++ Pointers vs Java References
- Marker interface in Java
- JPMS : Java Platform Module System
- Creating a Cell at specific position in Excel file using Java
- JAR files in Java
- Calculator Using RMI(Remote Method Invocation) in Java
- Fork Java | Course Structure
- Java Debugger (JDB)
- Object Graph in Java Serialization
- Break statement in Java
Types of References in Java
In Java there are four types of references differentiated on the way by which they are garbage collected.
- Strong References
- Weak References
- Soft References
- Phantom References
Prerequisite: Garbage Collection
Here ‘obj’ object is strong reference to newly created instance of MyClass, currently obj is active object so can’t be garbage collected.
- This type of reference is used in WeakHashMap to reference the entry objects .
- If JVM detects an object with only weak references (i.e. no strong or soft references linked to any object object), this object will be marked for garbage collection.
- To create such references java.lang.ref.WeakReference class is used.
- These references are used in real time applications while establishing a DBConnection which might be cleaned up by Garbage Collector when the application using the database gets closed.
Two different levels of weakness can be enlisted: Soft and Phantom
- Comprehensive Course
- Expert Guidance for Efficient Learning
- Hands-on Experience with Real-world Projects
- Proven Track Record with 100,000+ Successful Geeks
Please Login to comment...
- How To Earn Money Part-Time?
- 10 Best AI 3D Generators in 2024
- Top 10 Free Midjourney Prompt Generator 
- Top 10 Free AI Writing Tools for Content Creators
- 10 Best Free AI Art Generators to Create Image From Text [Free & Paid]
Improve your Coding Skills with Practice
What kind of Experience do you want to share?
Soft, Weak and Phantom references in Java
1. strong reference, 2. weakreference, 3. softreference, 4. phantomreference, 5. source code of this project on the github.
Strong reference is the most common kind of reference. We use this kind of reference every day.
The created instance of the Foo class is not available for the garbage collector while there is at least one link to this object.
WeakReference - this is the type of references that will be removed by the garbage collector on the next pass, if there are no other type references to the object.
You can get an object value from the WeakReference until the GC decides to collect the object. As soon as the GC decides to do it (not after the GC finalize the object and clear an allocated memory), you will get the NULL from the WeakReference . This happens when the GC is just marking the object for a further processing. It is important to understand, that all finalization actions are executed only after this. When we look at the PhantomReference , we’ll return to this point.
Let’s try to testing WeakReference behavior:
This test was successful.
Java provides us the WeakHashMap data structure. It’s a something like a HashMap , which uses the WeakReference as a key of the Map. If a key of the WeakHashMap becomes garbage, its entry is removed automatically.
How we can test a WeakHashMap behavior:
Results of weak tests:
The behavior of SoftReference is similar to WeakReference , but GC collect this kind of reference only when our application does not have enough of memory.
Let’s try to test it:
The GC collects our SoftReference before we get the OutOfMemoryError .
This behavior is a good reason to use SoftReferences as a cache for a data that is difficult to build in memory.
For example, a reading video or graphics data from a slow file storage. When your application has enough of memory, you can receive this data from the cache, but if application reaches of a memory limit, then the cache cleans. And now, you need restore this data on the next request.
However in many cases you need to prefer a cache based on the LRU algorithm.
The PhantomReferences are enqueued only when the object is physically removed from memory.
The get() method of the PhantomReference always returns NULL , specially to prevent you from being able to resurrect an almost removed object.
The PhantomReference provides you an ability to determine exactly when an object was removed from memory. In order for implementation this we need to work with a ReferenceQueue . When the referent object of a PhantomReference , removes from a memory then the GC enqueues the phantomReference in the referenceQueue and we can poll this reference from this queue.
Let’s look at the code:
For example, if you need to allocate memory for processing of a large video file, only after finish processing of a previous file and release memory (that was allocated in the previous step) then using a PhantomReference is a right decision. Because you can request a new part of memory exactly after the GC is release a previous used part. So, this reduces a chance to get the OutOfMemoryError when you already released a part of memory but the GC has not collected it yet.
Finalization may does not happened in a timely fashion, it is difficult to predict the number of garbage collection cycles while the object was waiting for finalization. It can lead to serious delay in actually cleaning up garbage objects, and become the reason of you can get an OutOfMemoryErrors even when most of the heap is garbage.
I wrote a simple utility to checking a code on memory leaks, which is using phantom references:
Example of using this tool:
Let’s look at the code of the memory leaks detector:
Strong, Soft, Weak and Phantom References (Java)
There are four distinct forms of references in the JVM, and indeed many of these apply to other garbage collected languages.
Soft references, weak references, phantom references.
It's important to know the differences, what affect they have on the collector and when you should be using them.
Strong references never get collected
Soft references only get collected if the JVM absolutely needs the memory. This makes them excellent for implementing object cache's.
Weak references only get collected if no other object references it except the weak references. This makes them perfect for keeping meta data about a particular object for the life time of the object.
Phantom references are objects that can be collected whenever the collector likes. The object reference is appended to a ReferenceQueue and you can use this to clean up after a collection. This is an alternative to the finalize() method and is slightly safer because the finalize() method may ressurect the object by creating new strong references. The PhantomReference however cleans up the object and enqueues the reference object to a ReferenceQueue that a class can use for clean up.
You saw me use the reference queue class in the previous example. A ReferenceQueue instance can be supplied as an argument to SoftReference, WeakReference or PhantomReference. When an object is collected the reference instance itself will be enqueued to the supplied ReferenceQueue. This allows you to perform clean up operations on the object. This is useful if you are implementing any container classes that you want to contain a Soft, Weak or Phantom reference and some associated data because you can get notified via the ReferenceQueue which Reference was just collected.
There is also a convience WeakHashMap that wraps all keys by a weak reference. Allowing you to easily store meta data against an object and have the map entry including the meta data removed and collected when the original object itself is unreachable.
- All Articles List
- 20 January 2020
Phantom References in Java
StrongReference (ordinary references that we create when creating an object):
In this example, cat is a strong reference.
SoftReference (soft reference). We had a lesson about such references.
WeakReference (weak reference). There was also a lesson about them here .
PhantomReference (phantom reference).
get() — returns the referenced object;
its finalize() method is called (if it is overridden)
if nothing changes once the finalize() method is finished and the object can still be deleted, then the phantom reference to the object is placed in a special queue: ReferenceQueue .