When to use Weak and Phantom references in Java
Asked Answered
R

4

8

I read many articles, but I don't understand - where do I need to use Weak and Phantom references in practice? Soft references - is a good choice for cache, as I understand. But weak and phantom, I don't know when to use. Please provide examples of real tasks where we need to use them.

Reconvert answered 9/7, 2012 at 14:49 Comment(1)
You don't need to use phantom references. These are for internal use. Youc an use weak references where ever you use soft references, except they have a shorter life. You can use weak references when they are only meaningful if another object also has a reference. e.g. listeners.Disraeli
B
8

You can use weak references for cache, simply like soft references as you said.

What good are PhantomReferences? I'm only aware of two serious cases for them: first, they allow you to determine exactly when an object was removed from memory. They are in fact the only way to determine that. This isn't generally that useful, but might come in handy in certain very specific circumstances like manipulating large images: if you know for sure that an image should be garbage collected, you can wait until it actually is before attempting to load the next image, and therefore make the dreaded OutOfMemoryError less likely.

Second, PhantomReferences avoid a fundamental problem with finalization: finalize() methods can "resurrect" objects by creating new strong references to them. So what, you say? Well, the problem is that an object which overrides finalize() must now be determined to be garbage in at least two separate garbage collection cycles in order to be collected. When the first cycle determines that it is garbage, it becomes eligible for finalization. Because of the (slim, but unfortunately real) possibility that the object was "resurrected" during finalization, the garbage collector has to run again before the object can actually be removed. And because finalization might not have happened in a timely fashion, an arbitrary number of garbage collection cycles might have happened while the object was waiting for finalization. This can mean serious delays in actually cleaning up garbage objects, and is why you can get OutOfMemoryErrors even when most of the heap is garbage.

for more details see this page : http://weblogs.java.net/blog/2006/05/04/understanding-weak-references

Baseball answered 9/7, 2012 at 15:20 Comment(3)
Weak refs are absolutely useless for caching.Slip
The probability of a finalizable object getting resurrected isn't "slim"--it's 100%; a finalizable object which would cease to exist but for the existence of a finalize method will have a strong reference to it placed on the stack when its finalizer starts running. The object can't be deleted until that reference (and all other rooted reference) have ceased to exist.Romilda
According to the OoME JavaDoc Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. So it doesn't matter if the large image is in memory or not, because if it is it will try to throw it out, before failing. Otherwise, you should know if you are holding any remaining references to it.Pilfer
S
5

Basically, you'll use a Weak ref when you want to associate some additional data with objects whose source code is not under your control. By using a weak ref you'll couple the lifecycle of your meta-objects to the lifecycle of the primary objects.

The main use case for phantom refs is implementing your own finalizer thread without the dangers associated with the default mechanism, which is forced to make the reference to the supposedly unreachable object accessible to the finalization code.

Soft refs are primarily for caching, but, as said in another post here, they can give quite disastrous effects in practice, undermining the very point of caching. A major GC (the one that will clear your Soft refs) usually doesn't happen until the pressure on your app's performance rises. This is the time when you need your cache the most, and the time you are most likely to lose it – all at once.

Slip answered 9/7, 2012 at 16:7 Comment(3)
According the OP, He want to know when to use Phantom references vs Weak References....Your reply doesn't answer his original question completelyArdell
No, you are misrepresenting the question, which is when to use weak and phantom references. It is not about how to choose between them, but when to use any of them. So even if this answer didn't deal with phantom refs (as of the time of your comment; it does deal with it now), everything it states is both on-topic and correct.Slip
I agree, the new answer covers the topic wellArdell
Q
3

I think this post answers your question pretty well.

What is the difference between a soft reference and a weak reference in Java?

Basically a soft reference is slightly stronger than a weak reference. A weak reference will be discarded on the next GC cycle, while a soft reference will stay in memory until there is memory pressure and the JVM wants to reclaim as much as it can.

You should think about how important is it to your program that the reference you have is still valid. For something that is extremely cheap to recreate a reference to, I would lean towards a WeakReference, but if it's a value from a DB you might lean towards the soft reference since you'd rather not rerun a query unless you really need to.

Quicklime answered 9/7, 2012 at 14:56 Comment(2)
Thank you. But I understand difference between this references types. I did not understand in what specific task can apply them.Reconvert
I added my view of when to use a Weak vs. Soft referenceQuicklime
L
0

SoftReference objects are not collected until all WeakReference objects have been garbage collected.

So put less important objects in WeakReference objects, and use SoftReference objects to hold more important object.

Given those facts you should use the good Reference objects depending on you need in term of garbage collection. The WeakReference are collected first, then the SoftReference and finally the PhantomReferences.

The documentation says :

  • Soft references are for implementing memory-sensitive caches
  • Weak references are for implementing canonicalizing mappings that do not prevent their keys (or values) from being reclaimed

By the way, in some case, for cache purpose, it can be a good idea to use WeakReference instead of SoftReference because the cache can be heavy in memory, and so, need to be cleaned.

For PhantomReference, the use is different. They are for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.

This article elaborate a bit on what can be the use of PhantomReference.

Levin answered 9/7, 2012 at 15:6 Comment(16)
you are pretty much right about weak and soft references. you are wrong about PhantomReferences. PhantomReferences are only useful as a replacement for the finalize method (aka resource cleanup). they have nothing to do with caching or when an object will get gc'ed.Gershon
@Gershon First I've never stated that PhantomReferences are for caching (I'm speaking of WeakReference in relation with what is stated in OP). Then I know it's a kind a replacement for finalize() but for the gc order I read it in Java Perf Tuning, and this link seems to say the same thing : docs.oracle.com/javase/7/docs/api/java/lang/ref/…Levin
your second-to-last sentence seems to imply that you would choose between the various types based on when they might be collected. my point is that you use phantoms refs completely differently from weak/soft refs, so that sentence is meaningless (and yes, you are correct about collection order, that's not my point).Gershon
You get a couple of things wrong. 1. You can't use a Phantom ref to reach the referent. 2. Weak refs are useless for caching. They don't delay the GCing of their referents at all. Such a cache will get cleared at the first minor GC.Slip
@Gershon I understand, I rewrote it.Levin
@MarkoTopolnik Weak refs are useless for caching. They don't delay the GCing of their referents at all. I don't say that, I say Weak ref delay the GC of Soft ref, I'm not speaking of their referent. And I disagree with you Weak refs are not useless for caching, ofc they will GC but that's the goal In the context I was thinking, cache is too large and so need to be reclaimed first.Levin
Weak refs don't delay anything---they get cleared as soon as there is no "normal" reference to the referent (it's not strongly reachable). That's why they fail as caches -- object will get into the young gen and can get cleared in a matter of seconds, with free heap still in plentiful supply.Slip
@MarkoTopolnik Weak refs ... get cleared as soon as there is no "normal" reference I know when they are cleared what I'm saying is that Soft are not GC if there is still Weak ref!! And for cache, I read that in Java Perf Tuning, I've never tried myself so you may be right. The author wrote that this statement open discussion ;). The conclusion he gives is to choose the appropriate Reference according to how expensive is to recreate the object.Levin
It's the other way round: soft are stronger than weak so if an object is softly reachable, the weak ref will not get cleared. Which confirms my statement that you need a soft ref for caching. As for using a weak cache, the overhead of just maintaining such a cache will soon drown out any advantages it may bring, considering how short-lived it is.Slip
@MarkoTopolnik Yes it's exactly what I'm saying, Soft are stronger so they are not gc if there is still Weak ref. Weak ref are less important so collected before Soft ref. That's whay I said Weak ref delay the GC of Soft ref, because they have to be collected before the GC can clean Soft ref.Levin
But that's not what I am saying: the life of the soft ref is in no way affected by the (non)existence of weak refs! A soft ref lives on with or without a weak ref -- it just doesn't care. Not so the other way 'round.Slip
@MarkoTopolnik From Java Performance Tuning ed2 : WeakReferences and SoftReferences differ essentially in the order in which the GC clears them. Simplistically, the GC does not clear SoftReference objets until all WeakReferences have been cleared.Levin
You are citing a simplistic account of things and reading more into it than written. The quote is entirely compatible with my statements and your inference that weakrefs somehow delay the collection of softrefs is arbitrary -- and false.Slip
Consider this statement: You don't come of age until you have lived out your teens'. Do the teens delay your coming of age?Slip
@MarkoTopolnik Unfortunatelly, the author didn't elaborate more on this sentence. "Delay" is maybe not the word in English sorry sometimes I use wrong words... I guess the sentence means that you have to wait to finish "teens year" before "coming to adult". By the way thanks for having share you're knowledges, and make things clearer.Levin
A final remark: most of the discussion about which ref is better for caching is just armchair talk since in a real project you'd never attempt to implement a cache from scratch: you'd use a battle-proven implementation such as ehcache. Good caching is chock-full of subtleties you just don't want to reinvent yourself and the lifecycle of objects on the heap is by no means dedicated to providing good cache performance. Modern caches don't even use the heap for caching, but off-heap storage, because they want to take full control over the lifecycle of cached objects.Slip

© 2022 - 2024 — McMap. All rights reserved.