When to use Weak and Phantom references in Java

2019-03-27 05:09发布

问题:

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.

回答1:

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



回答2:

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.



回答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.



回答4:

This article has a great answer to this question.



回答5:

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.