Is there a practical use for weak references?

27,873

Solution 1

If you want to keep a reference to something as long as it is used elsewhere e.g. a Listener, you can use a weak reference.

WeakHashMap can be used as a short lived cache of keys to derived data. It can also be used to keep information about objects used else where and you don't know when those objects are discarded.

BTW Soft References are like Weak references, but they will not always be cleaned up immediately. The GC will always discard weak references when it can and retain Soft References when it can.

There is another kind of reference called a Phantom Reference. This is used in the GC clean up process and refers to an object which isn't accessible to "normal" code because its in the process of being cleaned up.

Solution 2

Since weak reference can be claimed by garbage collector at any time, is there any practical reason to use it?

Of course there are practical reasons to use it. It would be awfully strange if the framework designers went to the enormous expense of building a weak reference system that was impractical, don't you think?

I think the question you intended to ask was:

What are realistic situations in which people use weak references?

There are many. A common one is to achieve a performance goal. When performance tuning an application one often must make a tradeoff between more memory usage and more time usage. Suppose for example there is a complex calculation that you must perform many times, but the computation is "pure" -- the answer depends only on the arguments, not upon exogenous state. You can build a cache -- a map from the arguments to the result -- but that then uses memory. You might never ask the question again, and that memory is would then be wasted.

Weak references possibly solve this problem; the cache can get quite large, and therefore time is saved if the same question is asked many times. But if the cache gets large enough that the garbage collector needs to reclaim space, it can do so safely.

The downside is of course that the cleanup policy of the garbage collector is tuned to meet the goals of the whole system, not your specific cache problem. If the GC policy and your desired cache policy are sufficiently aligned then weak references are a highly pragmatic solution to this problem.

Solution 3

If a WeakReference is the only reference to an object, and you want the object to hang around, you should probably be using a SoftReference instead.

WeakReferences are best used in cases where there will be other references to the object, but you can't (or don't want to have to) detect when those other references are no longer used. Then, the other reference will prevent the object from being garbage collected, and the WeakReference will just be another way of getting to the same object.

Two common use cases are:

  1. For holding additional (often expensively calculated but reproducible) information about specific objects that you cannot modify directly, and whose lifecycle you have little control over. WeakHashMap is a perfect way of holding these references: the key in the WeakHashMap is only weakly held, and so when the key is garbage collected, the value can be removed from the Map too, and hence be garbage collected.
  2. For implementing some kind of eventing or notification system, where "listeners" are registered with some kind of coordinator, so they can be informed when something occurs – but where you don't want to prevent these listeners from being garbage collected when they come to the end of their life. A WeakReference will point to the object while it is still alive, but point to "null" once the original object has been garbage collected.

Solution 4

We use it for that reason - in our example, we have a variety of listeners that must register with a service. The service keeps weak references to the listeners, while the instantiated classes keep strong references. If the classes at any time get GC'ed, the weak reference is all that remains of the listeners, which will then be GC'ed as well. It makes keeping track of the intermediary classes much easier.

Solution 5

The most common usage of weak references is for values in "lookup" Maps.

With normal (hard) value references, if the value in the map no longer has references to it elsewhere, you often don't need the lookup any more. With weakly referenced map values, once there are no other references to it, the object becomes a candidate for garbage collection

The fact that the map itself has a (the only) reference to the object does not stop it from being garbage collected because the reference is a weak reference

Share:
27,873

Related videos on Youtube

user496949
Author by

user496949

Updated on May 11, 2021

Comments

  • user496949
    user496949 about 3 years

    Possible Duplicate:
    Weak references - how useful are they?

    Since weak references can be claimed by the garbage collector at any time, is there any practical reason for using them?

    • Piotr Gwiazda
      Piotr Gwiazda over 12 years
      weblogs.java.net/blog/2006/05/04/understanding-weak-referenc‌​es - weak, soft and phantom references explained
    • BlueRaja - Danny Pflughoeft
      BlueRaja - Danny Pflughoeft over 12 years
      Events (callbacks) are a good one - events should always have weak-references. Unfortunately, in C#, even though events are a language-feature, they always use strong-references. This is a mistake of the language, and has caused lots of hard-to-find memory leaks in programs (there are libraries which fix this problem [and several other problems with events], such as CAB or the open source equivalent, bbv.Common.EventBroker).
    • Bayquiri
      Bayquiri over 12 years
      @BlueRaja-DannyPflughoeft, making the event references weak without doing anything else changes memory leak problems to non-deterministic premature deallocation problems, which are much worse.
    • BlueRaja - Danny Pflughoeft
      BlueRaja - Danny Pflughoeft over 12 years
      @Rotsor: There is a simple solution to that, on the VM's side - during garbage collection, consider any object currently running an event as having a reference. But there is no need to bring up that minor implementation detail here...
    • Bayquiri
      Bayquiri over 12 years
      @BlueRaja-DannyPflughoeft Let us discuss this in chat
    • Ahmad Shahwaiz
      Ahmad Shahwaiz over 6 years
      how about just turning the previous activity reference to null after the making the callback?
  • Bill K
    Bill K over 12 years
    Java (the language given in the tags) is specified not to use reference counting GC.
  • Bhushan
    Bhushan over 12 years
    I think Java GC can use reference counting as one of the strategy, of course it depends on the JVM. Can you give some resource which says that Java cannot use/never uses reference counting?
  • Voo
    Voo over 12 years
    Using weak references as a cache does have its problems though: See this That's specific to weak HashMap, but the general problem (using weak references as a cache) is the same to some degree.
  • Vishy
    Vishy over 12 years
    @Voo Agree than using WeakReferences are not as good as SoftReferences for a cache, however both have problems.
  • Abdul Hfuda
    Abdul Hfuda over 12 years
    The problem with this particular scenario is that you are hoping the GC will behave in a desirable way and do some of the work that is inherent to your optimization algorithm. I think in the most common GC policy implementations a weak reference to an object that has no strong reference will be blown away very quickly- usually on the first GC pass. I would even say its better to implement your own tracking of these 'answers' using strong references and drop them explicitly using your own domain knowledge and logic.
  • Voo
    Voo over 12 years
    Why WeakHashMap Sucks or the downsides of using weak references as a cache. Obviously no real problem with stop the world GC that runs only rarely, but we're moving away from that. You are hinting at that problem in your last paragraph, but the thing is: I don't want to use an inferior GC just so that I can use weak hashmaps - and at least in Java those new concurrent GCs are great (no idea how far .NET is down the road there, but I'm sure they're going in the same direction)
  • Voo
    Voo over 12 years
    Yeah soft references could help with the problem, but afaik the language doesn't really make any hard guarantees about them (ie they could be handled just as weak references) so then we depend on a specific GC implementation to avoid the problems. And as you say there are problems with softrefs either: (assume naive impl. - no idea how hotspot/ibm handle them atm!) If we just add objects until we run out of memory, then remove all of them at once, that isn't perfect either.
  • Vishy
    Vishy over 12 years
    Yes, you could find your application is running fine most of the time and suddenly all the SoftReferences get cleaned up at once and you have nothing cached. (Usually after a full GC) so just at the time you want your application to be fastest to catch up (as it just paused for a while) everything has to be brought back into the cache. i.e. it works well most of the time, except when you need it the most. :( One way around this is to have a small, fixed size cache of strong references and a second tier cache of weak/soft references.
  • Voo
    Voo over 12 years
    @Brushan The langauge spec demands that cycles be handled correctly, which means that while we can use ref counting, we still have to do a mark&sweep swipe once in a while to break up the cycles. That together with the performance problems of ref counting GCs compared to current concurrent algorithms makes it pretty much uninteresting.
  • ccoakley
    ccoakley over 12 years
    If my understanding is correct, this is extremely VM dependent. I thought weak references were removed when the GC fired, and didn't contractually oblige the GC to fire. If the GC doesn't fire, the links won't disappear, right? Is this a correctness issue? Do you explicitly call the GC after node deletion?
  • Voo
    Voo over 12 years
    Yeah :( My solution to the caching problem so far was to just use a strong cache of a particular size and fine tune the cache size if necessary. Far from optimal if the program will run on lots of different configurations - in that case the tiered approach may be worth the additional complexities.
  • Neil G
    Neil G over 12 years
    @ccoakley: Yes, I call gc.collect(). Is that enough to guarantee this works? The edge structure is complicated, and it would be a pain to have to explicitly disconnect things.
  • Vishy
    Vishy over 12 years
    Its worth having a look at LinkedHashMap as it supports a simple LRU cache.
  • ccoakley
    ccoakley over 12 years
    I believe your code is conditionally correct, with Sun's JVM. However, the JVM spec (chapter 3) specifies: "...the garbage-collection algorithm used, ... are left to the discretion of the implementor." This means that a (bad) conservative collector might not notice the reference missing and not delete the links at your explicit call to the gc. This is one reason why explicit gc calls are frowned upon; the exact behavior is not exactly platform independent. Take into account that my knowledge is quite limited AND dated on this subject, though.
  • Neil G
    Neil G over 12 years
    @ccoakley: I'm working in Python, but you're right though: the story is the same. I'll have to fix it at some point. On the bright side, I'm being very conservative with my references in order for this to work, so when I finally do explicitly remove the objects from the dictionaries, I can be sure that there will be no references keeping the link objects alive.
  • bestsss
    bestsss over 12 years
    Weak (or Soft) references should not be used as quick&dirty caches, aggressive GCs may evict the references almost immediately and the gain would be zero. Using references as cache would make the program dependent on the GC algorithm or just the parameters for the GC and can not be predicted reliably.
  • bestsss
    bestsss over 12 years
    @Voo, WeakHashMap cannot be used as cache at all, you want the values to be soft, not the keys. (Soft)RefMaps do work as cache and do that pretty well... except when the memory becomes tight and the application goes into a vicious cycle: due to failing caches. Back in the day (~2003) I used to like the quick&dirty caches via soft references but they are just unreliable, esp. w/o control over the GC and caches shall not be a driving force how to configure the GC.
  • bestsss
    bestsss over 12 years
    @Voo, you can pin a number of the most used entries but if you can do that, why bother just do all the stuff yourself
  • bestsss
    bestsss over 12 years
    The most common usage..., this is untrue. could be true for soft one but definitely not weak ones. WeakReferences are used where retaining the real reference would lead to a leak.
  • Voo
    Voo over 12 years
    @bestsss I assume you mean why use the tiered approach Peter proposes at all? The advantage I see compared to a single fixed size cache is that we have some guarantees about performance, but can still use the additional memory for speedups - that seems useful. Not the pathological behavior of a sole soft referenced cache, but we still use the memory available
  • bestsss
    bestsss over 12 years
    well, a good cache should not rely on a fixed size only but employ some usage statistics beyond LRU. If you do that, you dont need soft references any more. Also soft references behave horrible if you retain direct buffers or any other native objects. They are useful for heap memory intense caches only.
  • supercat
    supercat about 12 years
    Why are you suggesting that caching of objects to which no other references exist is a practical use for WeakReference? A much better use, which does not presume that garbage collections are infrequent, is management of notifications. An object may want to update another object when something happens as long as anyone is interested in seeing those updates, but not want to have that other object kept around merely for the purpose of receiving updates once nobody cares about them anymore.
  • Johann
    Johann over 9 years
    Maybe the original inclusion of weak references in Java was done to provide a band-aid to limited memory in those days. Things have evolved significantly since then and using more robust techniques that don't rely upon some iffy garabage collector suddenly taking out your reference at some random time is a better approach. I have written several mobile apps in Java and have yet to see a need for weak references.
  • TheBuzzSaw
    TheBuzzSaw over 8 years
    That URL doesn't seem to work anymore. cliffc.org/blog/2007/08/30/why-weakhashmap-sucks
  • Basil Bourque
    Basil Bourque about 6 years
    What class is WeakSet? I do not find it in Java 10 API.
  • Neil G
    Neil G about 6 years
    @BasilBourque Sorry, this was Python. I don't know Java. Anyway, like ccoakley said, it was not a good design.
  • Basil Bourque
    Basil Bourque about 6 years
    @NeilG Then I suggest you delete this Answer, if it is irrelevant.
  • Neil G
    Neil G about 6 years
    @BasilBourque: It answers the question: "Since weak references can be claimed by the garbage collector at any time, is there any practical reason for using them?"