How does the ReferenceQueue works? and How to use it on Projects?
Documents said: When a WeakReference or SoftReference has been cleaned, they will be enqueue the ReferenceQueue. What does that do this?
To understand ReferenceQueue first you need to understand the different between strong and weak references. Here's an article that can help you with that: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
What is a ReferenceQueue?
Non-strong references start returning null once the heap object they weakly refer to don't have any strong references to them. So the problem with non-strong references is that you never know when they will start returning null. ReferenceQueue is a provision provided by Java to help us know when the weakreference is eligible for GC, if and when we really want to know that. So how this should be done? If you have provided a ReferenceQueue while creating the weakreference then when that weakreference is eligible for GC, it is en-queued into that ReferenceQueue and then you can keep polling that ReferenceQueue when you wanna check if any weakreference has been enqueued in the ReferenceQueue.
Here is a good article with code for this:
http://learningviacode.blogspot.com/2014/02/reference-queues.html
Related
I know what WeakReference is and I read its documentation and many blogs and SO threads. However, it is still unclear to me whether the following flow can actually happen.
object X being referenced with strong reference strRef and weak reference weakRef
strRef is being cleared on a random thread
weakRef is being dereferenced on a random thread
the reference retrieved in the previous step is assigned to strRef
There are many discussions about how weak references are being cleared upon GC, but, to the best of my knowledge, GC does not happen after each reference clearance. Therefore, it looks like a weakly reachable object could potentially be "resurrected" by the step #3 above if GC did not happen between steps #2-#3.
Such a race condition is very inconvenient and even dangerous, therefore I think that there should be something that prevents it, but I want to be completely sure here.
So, is there a specification that ensures that weakly referenced objects can't be resurrected, and are there any caveats related to multithreading?
Therefore, it looks like a weakly reachable object could potentially be "resurrected" by the step #3 above if GC did not happen between steps #2-#3.
Correct, even if a GC it has run, not all weak references have to be cleared e.g. when a minor collection is run an object in tenured space is not cleaned up. Only a Full GC can ensure all weak references are cleared.
Such a race condition is very inconvenient and even dangerous, therefore I think that there should be something that prevents it,
It's something you must check for at any point given you have no idea when the background thread clears the strong reference. NOTE: clearing a strong reference just means setting a memory value to null nothing more.
is there a specification that ensures that weakly referenced objects can't be resurrected, and are there any caveats related to multithreading?
Even discarded object can be resurrected by setting a reference to this in the finalise method. I would recommend you not rely on this behaviour. References setting are not a source of messaging nor an operation which has much thread safety guarantees.
I thought I could rely on weak references in order to subscribe these UI classes to an event bus, such that there will be no need to unsubscribe them later.
You can but you have to check whether the listener is still active. Just because you could get a weak reference to it doesn't mean you didn't intend to discard it.
Weak references allows GC to collect the references in next GC Cycle whereas Soft Reference will keep the reference until memory is full and before throwing out of memory error,it will remove soft references.
Where we will be using these references?
Which reference will be best for implementing caching?
For eg:If I use soft reference for caching,then it will be cleared when memory is full.
But lets suppose,I have fetched some database details and put that in memory and cached that detail in soft reference and now if i removed some key value from memory,it will still be there in cache.Do we need to use weak reference in this case?How the decision should be made.
Soft References are used for caching in most cases. You want to keep data in RAM as long as it possible, but it is better to purge cache than die with OOM.
Weak references can be used (for example) to keep extra info about your class. You have class User and you want to store some additional info, which should be deleted at the moment when user is deleted (you do not want to do it manually since it is bolierplate code). So, you use WeakHashMap using User as key, and when there is no reference to user, it is deleted from this map as well.
By the way: in languages with references counting weak references are used to prevent reference cycles, but java GC removes "islands of isolation", so this usage of weak reference is not for java.
Weak references allows GC to collect the references in next GC Cycle whereas Soft Reference will keep the reference until memory is full and before throwing out of memory error,it will remove soft references.
You are reading more into the docs than they actually say. All objects that are softly reachable (which precludes them being strongly reachable) will be cleaned up and released before the VM throws an OutOfMemoryError, but the VM is in no way required to preserve them past the point when they are initially determined to be softly reachable. The docs do not forbid that they be reclaimed in the same GC cycle in which they are found to be softly reachable.
Generally speaking, however, you can suppose that the GC will prefer to process phantom reachable and weakly reachable objects first.
Where we will be using these references? Which reference will be best for implementing caching?
The docs say this:
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, and phantom references are for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.
You go on to ask:
For eg:If I use soft reference for caching,then it will be cleared when memory is full. But lets suppose,I have fetched some database details and put that in memory and cached that detail in soft reference and now if i removed some key value from memory,it will still be there in cache.Do we need to use weak reference in this case?How the decision should be made.
If you want to build a cache that can discard entries whose keys cease to be strongly reachable (which may mean that those entries can no longer be retrieved), that is squarely in the center of the intended purpose for weak references. The cache internally holds only a weak reference to the key of each entry, and it registers those references with a ReferenceQueue that lets it know when they should be discarded. This is precisely how WeakHashMap works.
If you want to build a cache that can respond to high memory demand by discarding entries, then that is the intended purpose of soft references (to the values); such a cache would work similarly to WeakHashMap, but with use of soft references to the values instead of weak references to the keys. The two could be combined, of course.
Note, by the way, that Reference objects become relevant to GC only when their referents cease to be strongly reachable. In particular, having a SoftReference to an object does not in itself guarantee that that object will ever be reclaimed, no matter what the demand is on memory. No object that is strongly reachable is ever eligible for finalization or reclamation.
If you are implementing your own cache, use a Soft Reference.
I once maintained a legacy system that used a cache of Weak References to store large objects that were very expensive to create. Almost every time a thread tried to fetch an object from that cache, it had already been GC'ed so the objects had to be expensively recreated a lot! It was practically like the cache wasn't there.
But lets suppose,I have fetched some database details and put that in memory and cached that detail in soft reference and now if i removed some key value from memory,it will still be there in cache. Do we need to use weak reference in this case?How the decision should be made.
I'm not sure I understand your question. When the original "hard" reference to those details is GC'ed it can still be in the cache of soft references. If you remove the item from the cache then there are no more references to the details at all so it will be GC'ed next time no matter what kind of reference used to point to it.
There are very few times when a WeakReference is useful. See Weak references - how useful are they? for some examples
Which reference will be best for implementing caching?
for caching use SoftReference class, the whole point of caching things is to keep it prepared for quick use - if memory is available. So when there is little memory ten its ok to flush your cache.
WeakReference are perfect for avoiding reference leaks, it happens when you have some static object or thread which keeps reference to object whose lifetime is shorter that this object/thread. I use a lot of WeakReference - s in android development, especially with AsyncTask's whose lifetime is often longer than of Activity-s lifetime which created them.
... Do we need to use weak reference in this case?
once you remove such entry from your cache collection it will be garbage collected, so no need for WeakReference.
I have never used SoftReferences - but thats because I mostly code under android platform, and acording to its docs http://developer.android.com/reference/java/lang/ref/SoftReference.html, they are useless for caching - at least under this platform.
I know that for PhantomReference's in the ReferencesQueue, one has to handle and empty the ReferenceQueue oneself.
In the case of WeakReferences in the ReferenceQueue, are the WeakReferences automatically removed from the ReferenceQueue?
We've used a strategy as an alternative to finalizers as described here:
http://resources.ej-technologies.com/jprofiler/help/doc/indexRedirect.html?http&&&resources.ej-technologies.com/jprofiler/help/doc/helptopics/config/finalizers.html
but we don't want to have another thread for removing PhantomReference's from the ReferenceQueue.
So we used WeakReferences instead, assuming that they are automatically removed from the ReferenceQueue. Is this a correct assumption? Thank you.
Yes, you are correct. Unless some whacky finalization code resurrects them.
Here's a good article explaining the situation: https://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html
Weak references will be GC'ed along with the object they reference, providing there is no other references to that object. Hence weak references in a ReferenceQueue will not do what you are expecting them to do. The weak reference will not prevent the object from being GC'ed, but once it is you will not be able to get an indirect reference to it in the same way as a phantom reference.
Saying that try using weak references on Websphere and you'll find that the garbage collector is ultra aggressive in clearing them out, whether you like it or not.
You will need to clean the phantom references up yourself with a daemon thread, possibly including some form of destructor.
I understand that weak references are at the mercy of the garbage collector, and we cannot guarantee that the weak reference will exist. I could not see a need to have weak reference, but sure there should be a reason.
Why do we need weak reference in java?
What are the practical (some) uses of weak reference in java? If you can share how you used in your project it will be great!
It's actually quite often a bad idea to use weak hashmaps. For one it's easy to get wrong, but even worse it's usually used to implement some kind of cache.
What this does mean is the following: Your program runs fine with good performance for some time, under stress we allocate more and more memory (more requests = more memory pressure = probably more cache entries) which then leads to a GC.
Now suddenly while your system is under high stress you not only get the GC, but also lose your whole cache, just when you'd need it the most. Not fun this problem, so you at least have to use a reasonably sized hard referenced LRU cache to mitigate that problem - you can still use the weakrefs then but only as an additional help.
I've seen more than one project hit by that "bug"..
The most "unambiguously sensible" use of weak references I've seen is Guava's Striped, which does lock striping. Basically, if no threads currently hold a reference to a lock variable, then there's no reason to keep that lock around, is there? That lock might have been used in the past, but it's not necessary now.
If I had to give a rule for when you use which, I'd say that soft references are preferable when you might use something in the future, but could recompute it if you really needed it; weak references are especially preferable when you can be sure the value will never be needed after a reference goes out of memory. (For example, if you use the default reference equality for a particular equals(Object) implementation for a map key type, and the object stops being referenced anywhere else, then you can be sure that entry will never be referenced again.
The main reason for me to use weak references is indirectly, through a WeakHashMap.
You might want to store a collection of objects in a Map (as a cache or for any other reason), but don't want them to be in memory for as long as the Map exists, especially if the objects are relatively large.
By using a WeakHashMap, you can make sure that the reference from the Map isn't the only thing keeping the object in memory, since it'll be garbage collected if no other references exist.
Say you need to keep some information as long as an object is referenced, but you don't know when it will go away, you can use a weak reference to keep track of the information.
Yes and it has good impact.
Example of "widget serial number" problem above, the easiest thing to do is use the built-in WeakHashMap class. WeakHashMap works exactly like HashMap, except that the keys (not the values!) are referred to using weak references. If a WeakHashMap key becomes garbage, its entry is removed automatically. This avoids the pitfalls I described and requires no changes other than the switch from HashMap to a WeakHashMap. If you're following the standard convention of referring to your maps via the Map interface, no other code needs to even be aware of the change.
Reference
Weak Refernce Objects are needed to JVM platform to ensure means against the memory leaks.
As Java Developers should know, Java can leak, more than expected. This statement is particurarly true in those cases in which an Object is no longer used but some collection still refence strongly that instance: a very simple but recurrent example of memory leak, in fact that memory area will not be deallocated until the strong reference exists.
In the above case, a Weak Reference Object in the collection assures that: without a strong references chain, but with only weak chains, the instance can be elcted as garbace collectable.
In my opinion, all features provided by the Java Platform are useful to some extent: very skilled programmer can drive Java to be fast and reliable as C++ writing very high quality code.
Decoupling from pub-sub or event bus
A WeakReference is good when you want to let an object head for garbage-collection without having to gracefully remove itself from other objects holding an reference.
In scenarios such as publish-subscribe or an event bus, a collection of references to subscribing objects is held. Those references should be weak, so that the subscriber can conveniently go out of scope without bothering to unsubscribe. The subscriber can just “disappear” after all other places in the app have released their strong reference. At that point, there is no need for the subscription list or event bus to keep hanging on to the subscriber. The use of WeakReference allows the object to continue on its way into oblivion.
The subscribing object may have been subscribed without its knowledge, submitted to the pub-sub or event bus by some other 3rd-party object. Coordinating a call to unsubscribe later in the life-cycle of the subscriber can be quite cumbersome. So letting the subscriber fade away without formally unsubscribing may greatly simplify your code, and can avoid difficult bugs if that unsubscribing coordination were to fail.
Here is an example of a thread-safe set of weak references, as seen in this Answer and this Answer.
this.subscribersSet =
Collections.synchronizedSet(
Collections.newSetFromMap(
new WeakHashMap <>()
)
);
Note that the entry in the set is not actually removed until after garbage-collection actually executes, as discussed in linked Answer above. While existing as a candidate for garbage-collection (no remaining strong references held anywhere), the item remains in the set.
It is required to make Java garbage collection deterministic. (From the slightly satirical point of view with some truth to it).
I have a cache built from a Map to SoftReferences. When they are added they get put into another queue to be lazily compressed down via gzip or some such.
My idea is this: I want to have WeakReferences to the objects in the compress queue, so that when the compressor task gets to the object, if it is already gone we needn't bother compressing it - and also that the compressor's queue doesn't keep objects alive that would otherwise be GC'd.
So if there is exactly one SoftReference and one WeakReference, does the semantic of SoftReference apply still?
Yes the semantic of SoftReferences still applies: SoftReferences are stronger than WeakReferences.
WeakReferences are basically treated as non existing for the GC. So an object that is only weakly reachable may be GCed immediately. Objects only reachable by a SoftReferences as the strongest type, however, are only considered for GCing if demands on memory needs to be fullfilled.
So if there are both soft and weak references, the semantic of SoftReference is applied.
Weak reference objects, which do not
prevent their referents from being
made finalizable, finalized, and then
reclaimed.
http://download.oracle.com/javase/6/docs/api/java/lang/ref/WeakReference.html
Soft reference objects, which 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.
http://download.oracle.com/javase/6/docs/api/java/lang/ref/SoftReference.html
yes, there is no problem to GC the object that has as many soft/weak references as you want, until it has almost one strong reference.
You should notice that Weak Reference always collect before Soft Reference. And Soft Reference often use to cache something.
It means: at that time, no longer it needs to survive, but, at sometimes in the future, maybe you need it again, and Java will not work again to instance a new object.