Java: difference between strong/soft/weak/phantom reference
Asked Answered
S

7

215

I have read this article about different types of references in Java (strong, soft, weak, phantom), but I don't really understand it.

What is the difference between these reference types, and when would each type be used?

Steady answered 21/3, 2012 at 16:43 Comment(7)
weblogs.java.net/blog/2006/05/04/understanding-weak-referencesRoughrider
I have read that document, it doesn't help me imagine what difference. (maybe because it's a hard-read document)Steady
If you read that article and still don't understand, do you have specific questions about it? It's hard to respond to "please explain Foo to me," "here's what it means," "I don't get it" without specifics as to which parts you don't get.Reverberation
possible duplicate of Understanding Java's Reference classes: SoftReference, WeakReference, and PhantomReferenceRoughrider
@LouisWasserman The top link is no longer valid.Cazzie
adding to the Q: strongRef --> weakRef --> objA. Now, will objA will be GCed or not, as it has an indirect ref from strongRef.Diplopia
Does this answer your question? Understanding Java's Reference classes: SoftReference, WeakReference, and PhantomReferencePriorate
F
173

Java provides two different types/classes of Reference Objects: strong and weak. Weak Reference Objects can be further divided into soft and phantom.

  • Strong
  • Weak
    • soft
    • phantom

Let's go point by point.

Strong Reference Object

StringBuilder builder = new StringBuilder();

This is the default type/class of Reference Object, if not differently specified: builder is a strong Reference Object. This kind of reference makes the referenced object not eligible for GC. That is, whenever an object is referenced by a chain of strong Reference Objects, it cannot be garbage collected.

Weak Reference Object

WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);

Weak Reference Objects are not the default type/class of Reference Object and to be used they should be explicitly specified like in the above example. This kind of reference makes the reference object eligible for GC. That is, in case the only reference reachable for the StringBuilder object in memory is, actually, the weak reference, then the GC is allowed to garbage collect the StringBuilder object. When an object in memory is reachable only by Weak Reference Objects, it becomes automatically eligible for GC.

Levels of Weakness

Two different levels of weakness can be enlisted: soft and phantom.

A soft Reference Object is basically a weak Reference Object that remains in memory a bit more: normally, it resists GC cycle until no memory is available and there is risk of OutOfMemoryError (in that case, it can be removed).

On the other hand, a phantom Reference Object is useful only to know exactly when an object has been effectively removed from memory: normally they are used to fix weird finalize() revival/resurrection behavior, since they actually do not return the object itself but only help in keeping track of their memory presence.

Weak Reference Objects are ideal to implement cache modules. In fact, a sort of automatic eviction can be implemented by allowing the GC to clean up memory areas whenever objects/values are no longer reachable by strong references chain. An example is the WeakHashMap retaining weak keys.

Frustrated answered 7/5, 2014 at 13:50 Comment(1)
adding to the Q: strongRef --> weakRef --> objA. Now, will objA will be GCed or not, as it has an indirect ref from strongRef.Diplopia
H
83

Weak Reference :

A weak reference, simply put, is a reference that isn't strong enough to force an object to remain in memory. Weak references allow you to leverage the garbage collector's ability to determine reachability for you, so you don't have to do it yourself.

Soft Reference :

A soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers. An object which is only weakly reachable (the strongest references to it are WeakReferences) will be discarded at the next garbage collection cycle, but an object which is softly reachable will generally stick around for a while.

Phantom Reference :

A phantom reference is quite different than either SoftReference or WeakReference. Its grip on its object is so tenuous that you can't even retrieve the object -- its get() method always returns null. The only use for such a reference is keeping track of when it gets enqueued into a ReferenceQueue, as at that point you know the object to which it pointed is dead.

This text was extracted from: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references

Horseman answered 10/5, 2012 at 7:44 Comment(6)
While everything in this answer looks correct, it also looks to me like there may be an error on the linked webpage. The Javadoc for package java.lang.ref and that for PhantomReference suggest that an object is not garbage collected until after it is no longer "phantom reachable", implying that (unlike SoftReference) a PhantomReference must be dequeued before the object it refers to can be garbage collected...and its being enqueued does not indicate that the associated memory has been freed.Estragon
For the record, I would much rather live in a world where that blog post is correct.Estragon
@TheodoreMurdock The javadoc is correct. A phantom reference does not impede garbage collection at all. Once an object is enqueued, it cannot be saved even by a finalizer, as finalizers have already run. It's dead, but not yet gone.Effectually
@Effectually Actually, a phantom reference does in fact impede garbage collection after it is enqueued...I realized this recently when a bug caused a cleanup thread to exit early. The existence of phantom references was sufficient to ensure that every phantom referenced object was retained in my heap dump, unavailable for collection...if you fail to process the queue, or fail to make the phantom reference eligible for gc when processing the queue (and do not clear() the phantom reference), then your memory leak will include both the phantom reference and the referenced object.Estragon
"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." source: Java8 API Docs PhantomReferenceMatronize
adding to the Q: strongRef --> weakRef --> objA. Now, will objA will be GCed or not, as it has an indirect ref from strongRef.Diplopia
C
46

This article can be super helpful to understand strong, soft, weak and phantom references.


To give you a summary,

If you have a strong reference to an object, then the object can never be collected/reclaimed by GC (Garbage Collector).

If you only have weak references to an object (with no strong references), then the object will be reclaimed by GC in the very next GC cycle.

If you only have soft references to an object (with no strong references), then the object will be reclaimed by GC only when JVM runs out of memory.

We create phantom references to an object to keep track of when the object gets enqueued into the ReferenceQueue. Once you know that you can perform fine-grained finalization. (This would save you from accidentally resurrecting the object as phantom-reference don't give you the referrant). I'd suggest you reading this article to get in-depth detail about this.


So you can say that, strong references have ultimate power (can never be collected by GC)

Soft references are powerful than weak references (as they can escape GC cycle until JVM runs out of memory)

Weak references are even less powerful than soft references (as they cannot escape any GC cycle and will be reclaimed if object have no other strong reference).


Restaurant Analogy

  • Waiter - GC
  • You - Object in heap
  • Restaurant area/space - Heap space
  • New Customer - New object that wants table in restaurant

Now if you are a strong customer (analogous to strong reference), then even if a new customer comes in the restaurant or what so ever happnes, you will never leave your table (the memory area on heap). The waiter has no right to tell you (or even request you) to leave the restaurant.

If you are a soft customer (analogous to soft reference), then if a new customer comes in the restaurant, the waiter will not ask you to leave the table unless there is no other empty table left to accomodate the new customer. (In other words the waiter will ask you to leave the table only if a new customer steps in and there is no other table left for this new customer)

If you are a weak customer (analogous to weak reference), then waiter, at his will, can (at any point of time) ask you to leave the restaurant :P

Cunaxa answered 15/12, 2018 at 5:16 Comment(3)
Damn, now I want to hear a story starting with "A soft reference comes to a bar ..."Carnegie
Upvoted for the "waiter" story... So easy to understand by the story...Serology
I really impressed with Restaurant Analogy story and that example is really easy to understand, So upvoted.Lovesick
C
27

The simple difference between SoftReference and WeakReference is provided by Android Developer.

The difference between a SoftReference and a WeakReference is the point of time at which the decision is made to clear and enqueue the reference:

  • A SoftReference should be cleared and enqueued as late as possible, that is, in case the VM is in danger of running out of memory.

  • A WeakReference may be cleared and enqueued as soon as is known to be weakly-referenced.

Commutate answered 8/4, 2012 at 12:1 Comment(0)
P
17

The three terms that you have used are mostly related to Object's eligibility to get Garbage collected .

Weak Reference :: Its a reference that is not strong enough to force the object to remain in memory . Its the garbage collector's whims to collect that object for garbage collection. You can't force that GC not to collect it .

Soft Reference :: Its more or less same like the weak reference . But you can say that it holds the object a bit more strongly than the weak reference from garbage collection.

If the Garbage collectors collect the weak reference in the first life cycle itself, it will collect the soft reference in the next cycle of Garbage collection.

Strong Reference :: Its just opposite to the above two kind of references . They are less like to get garbage collected (Mostly they are never collected.)

You can refer to the following link for more info :

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html

Propene answered 21/3, 2012 at 17:7 Comment(3)
I think this is wrong - "If the Garbage collectors collect the weak reference in the first life cycle itself, it will collect the soft reference in the next cycle of Garbage collection." It is not necessarily that way, how can you be so sure that they occur in consecutive run of GC? GC can allow soft referenced objects to live even in 2nd run and 3rd run too. There is not documentation for it, if there is then please mention the link specifying.Brazell
Also, your answer is a little vague, look at this sentence ' Its more or less same like the weak reference . But you can say that it holds the object a bit more strongly than the weak reference from garbage collection.' - he is clearly asking about the difference and not similarities, all these words add more confusion than clarity to the topic.Brazell
@SaurabhPatil -- Missed your comment. Here goes the answers . 1. "he is clearly asking about the difference and not similarities" -- Refer to the description of the question (not "only" the title) "Please give me some advice, and please give me some example to describe". 2. "But you can say that it holds the object a bit more .... " I think SOF gives an option to down-vote and give new answers too.Propene
F
13

Strong References

These are your regular object references which we code daily:

Employee emp = new Employee();

The variable “emp” holds a strong reference to an Employee object and objects that are reachable through any chain of strong references are not eligible for garbage collection. Usually, this is what you want but not always. Now suppose we are fetching lots of employees from database in a collection or map, and we need to do a lot of processing on them regularly, So in order keep performance we will keep them in the cache.

As far as this is good but now we need different data and we don’t need those Employee objects and these are not referenced from anywhere except the cache. Which is causing a memory leak because these objects are not in use but still not eligible for the garbage collection and we cannot remove those objects from cache because we don’t have reference to them? So here either we need to empty the entire cache manually which is tedious or we could use other kind references e.g. Weak References.

Weak References

A weak reference does not pin an object into memory and will be GC’d in next GC cycle if not referenced from other references. We can use WeakReference class which is provided by Java to create above kind of caches, which will not store objects which are not referenced from somewhere else.

WeakReference<Cache> cache = new WeakReference<Cache>(data);

To access data you need to call cache.get(). This call to get may return null if the weak reference was garbage collected: you must check the returned value to avoid NPEs. Java provides collections that use weak references e.g., the WeakHashMap class stores keys (not values) as weak references. If the key is GC’d then the value will automatically be removed from the map too.

Since weak references are objects too we need a way to clean them up (they’re no longer useful when the object they were referencing has been GC’d). If you pass a ReferenceQueue into the constructor for a weak reference then the garbage collector will append that weak reference to the ReferenceQueue before they’re finalized or GC’d. You can periodically process this queue and deal with dead references.

Soft References

A SoftReference is like a WeakReference but it is less likely to be garbage collected. Soft references are cleared at the discretion of the garbage collector in response to memory demand. The virtual machine guarantees that all soft references to softly reachable objects will have been cleared before it would ever throw an OutOfMemoryError.

Phantom References

Phantom references are the weakest of all reference types, calling get on them will always return null. An object is phantomly referenced after it has been finalized, but before its allocated memory has been reclaimed, As opposed to weak references which are enqueued before they’re finalized or GC’d Phantom references are rarely used.

So how are they useful? When you construct a phantom reference you must always pass in a ReferenceQueue. This indicates that you can use a phantom reference to see when your object is GC’d.

Hey, so if weak references are enqueued when they’re considered finalize but not yet GC’d we could create a new strong reference to the object in the finalizer block and prevent the object being GC’d. Yep, you can but you probably shouldn’t do this. To check for this case the GC cycle will happen at least twice for each object unless that object is reachable only by a phantom reference. This is why you can run out of heap even when your memory contains plenty of garbage. Phantom references can prevent this.

You can read more on my article Types of References in Java(Strong, Soft, Weak, Phantom).

Filibertofilibuster answered 20/3, 2018 at 7:39 Comment(2)
you wrote that weak refrences will be GC'ed in next cycle if not refrenced from other refrences... but should not happen the same thing to stron refrences? if stron refrence is not accessed in any way then gets cleared... then if so then where is the difference again ... ? #confusedFingerstall
If an object is getting referred from let's say s1 (strong) and s2 (strong), the object will not be eligible for garbage collection until both s1 and s2 are dereferenced but if the object is getting referred from s1 (weak) and s2 (strong) then object will be eligible for garbage collection in the next GC cycle when it gets dereferenced from s2 only, because s1 is a weak reference and if object does not have any other reference except the weak one it is eligible for GCFilibertofilibuster
C
11

4 degrees of reference - Strong, Weak, Soft, Phantom

Strong - is a kind of reference, which makes the referenced object not eligible for GC. builder classes. eg - StringBuilder

Weak - is a reference which is eligible for GC.

Soft - is a kind of reference whose object is eligible for GC until memory is avaiable. Best for image cache. It will hold them till the memory is available.

Phantom - is a kind of reference whose object is directly eligible for GC. Used only to know when an object is removed from memory.

uses:

  1. Allows you to identify when an object is exactly removed from memory.

  2. when finalize() method is overloaded, then GC might not happen in timely fashion for GC eligible objects of the two classes. So phantom reference makes them eligible for GC before finalize(), is why you can get OutOfMemoryErrors even when most of the heap is garbage.

Weak references are ideal to implement the cache modules.

Checkrein answered 29/7, 2015 at 17:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.