19

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!
18bytes
  • 5,951
  • 7
  • 42
  • 69
  • 3
    This feature is quite uncommon. Just a read for everyone who visits this question: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references – nhahtdh Jun 27 '12 at 17:12
  • part of the explanation: http://stackoverflow.com/questions/154724/when-would-you-use-a-weakhashmap-or-a-weakreference – Denis Tulskiy Jun 27 '12 at 17:12
  • Its possible to do a web search (not that it wasnt done), but you don't get the insights or answers such as below. – 18bytes Jun 27 '12 at 18:10
  • check this example from Android http://stackoverflow.com/a/21441743/304371 – Artur A Feb 17 '14 at 09:33
  • Related Question: [*When would you use a WeakHashMap or a WeakReference?*](https://stackoverflow.com/q/154724/642706) – Basil Bourque Oct 13 '18 at 20:11
  • @nhahtdh the post is now available at https://web.archive.org/web/20061130103858/http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html – mjn42 Jan 30 '19 at 08:38

8 Answers8

20

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"..

Voo
  • 29,040
  • 11
  • 82
  • 156
  • +1 for shareing, I also believe SoftReferences is more appropriate for caching. – bpgergo Jun 27 '12 at 18:08
  • @bpgergo I always have to look up in the documentation which is which. Actually weak references are the weaker ones (I should be able to remember that), so the problem is less obvious there because Hotspot will remove the reference on every GC. That basically means you use the cache only between GCs and since small GCs happen quite often you'll not use very much of the cache to begin with. The real problem are actually soft references because the app runs fine for some time and then takes a real performance hit. Amended the post a bit to clarify that. – Voo Jun 27 '12 at 18:35
  • 1
    There's a good usage case for weak hashmaps: for caching instances of immutable objects, especially if application code will frequently be comparing against each other. If I create an object instance which is the same as a cached one to which a strong reference already exists, it's likely better--and unlikely to be worse--to abandon the new one and use the old one than to keep using the new one. The advantage comes from the fact that the other strong reference exists; the existence in the cache of objects to which strong references no longer exist does not help performance. – supercat Jan 29 '13 at 18:32
  • 1
    @Voo Not fully agree, it all comes to a trade off, Guava Cache as an example uses weakReferences extensively as well as other cachine solutions, EHCache, Cassandra, Infinispan. The issue with the standard LRU caching techniques is a slow performance. – Ivan Voroshilin Apr 13 '16 at 19:16
7

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.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • In most cases where `WeakReference` is appropriate, the weak reference exists not to encapsulate the state of its target, but rather its identity (i.e. the set of other references that exist to it). If that set of other references is empty, the `WeakReference` will cease to encapsulate anything of value. – supercat Aug 09 '13 at 20:28
  • @Louis Wasserman +1 for the 2 part, for the 1-st I would add Guava Cache's WeakReference as a value of a map. It is one of multiple options to configure one. A WeakReference is useful for e.g. A FIFO chain of short-running computable tasks. Once the whole chain is computed, a Weak-Reference can be GC-ed. – Ivan Voroshilin Apr 13 '16 at 19:22
5

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.

pcalcao
  • 15,789
  • 1
  • 44
  • 64
3

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.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
2

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

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
1

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.

Paolo Maresca
  • 7,396
  • 4
  • 34
  • 30
1

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

It is required to make Java garbage collection deterministic. (From the slightly satirical point of view with some truth to it).

Community
  • 1
  • 1
jpe
  • 1,013
  • 6
  • 14
  • I do not see the point, sorry. What do you mean for "determinism"? GC is non-deterministic by nature, this simply mean: the predictability in memory management introduced by the programmer cannot exist within the GC (it is always an heuristic algorithm). Tuning of the GC, normally, cannot enhance the determinism as per above. – Paolo Maresca May 08 '14 at 14:09
  • The nature of my comment was slightly ironic thus terminology was used liberally. But by using the referenced trick involving a weak reference it is possible to find out when the object under observation has indeed been garbage collected. So it is possible to actually peek into the otherwise completely opaque garbage collection of Java and, if needed, wait for an object to get garbage collected before proceeding. So "deterministic" in that sense. – jpe May 12 '14 at 07:16