Weak/Soft references?

Discussion in 'Java' started by Tegiri Nenashi, Jul 9, 2008.

  1. I'm not sure I ever saw a convincing example. Let's consider the two
    frequented in the literature.

    1. HashMap (why not other collection?). I understand that if a
    reference to HashMap is still reachable, the whole HashMap and their
    references would be reachable, if the reference to HashMap is gone,
    the referred objects (keys and values) would decrement their counts
    (although counts don't really matter in mark-and-sweep method) . If a
    key and a value is not reference anywhere else, then key is supposed
    to be marked as garbaged collected. Finally, with the key holding no
    references, it is value that is marked to be garbage collected as
    well.

    2. Listeners. Let's assume a button widget declares a click listener.
    So we have a circular reference, and both objects would be garbage
    collected when no longer referenced without a problem.

    The problem I can imagine is crossing programming environment
    boundaries with native calls, but I fail to see this idea supported
    anywhere in the literature.

    Am I missing something obvious? (Except the idea of a reference that
    not guaranteed to be valid at any time being a very insult to common
    sense in programming?)
     
    Tegiri Nenashi, Jul 9, 2008
    #1
    1. Advertising

  2. Tegiri Nenashi wrote:
    > I'm not sure I ever saw a convincing example. Let's consider the two
    > frequented in the literature.


    I'm still not sure when one would use WeakReferences, but SoftReferences
    have good uses.

    > Am I missing something obvious? (Except the idea of a reference that
    > not guaranteed to be valid at any time being a very insult to common
    > sense in programming?)


    The most common example, which you seem to have missed is caching, which
    is what SoftReferences are used for. The idea is that you want to keep
    something in memory for time performance reasons, but, if memory gets
    low, you don't actually need it in memory. The solution is a
    SoftReference: it hangs around until the memory starts getting low.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Jul 9, 2008
    #2
    1. Advertising

  3. Tegiri Nenashi

    jolz Guest

    > I'm still not sure when one would use WeakReferences

    I'v never had to use myself, but there was exactly one time when I was
    really surprised that library I'm using does't use WeakHashMap. The
    problem was with log4j - I was getting logger with name corresponding to
    my task, and there were lots of differently named tasks. There was no
    returnLogger() method, so after tasks were finished, logger's memory was
    never reclaimed. Even with returnLogger() or similar method it's simply
    more convenient to let WeakHashMap remember about releasing memory.
     
    jolz, Jul 9, 2008
    #3
  4. On Jul 9, 11:11 am, Joshua Cranmer <> wrote:
    > Tegiri Nenashi wrote:
    > > I'm not sure I ever saw a convincing example. Let's consider the two
    > > frequented in the literature.

    >
    > I'm still not sure when one would use WeakReferences, but SoftReferences
    > have good uses.
    >
    > > Am I missing something obvious? (Except the idea of a reference that
    > > not guaranteed to be valid at any time being a very insult to common
    > > sense in programming?)

    >
    > The most common example, which you seem to have missed is caching, which
    > is what SoftReferences are used for. The idea is that you want to keep
    > something in memory for time performance reasons, but, if memory gets
    > low, you don't actually need it in memory. The solution is a
    > SoftReference: it hangs around until the memory starts getting low.


    I admit I overlooked caching because I never if ever used it. Sure I
    use some auxiliary structures that speed up processing, but data there
    never expire.

    OK, here is one more idea I don't understand. Suppose we have a global
    map that caches up some things and which one can grow to overwhelm the
    available memory. Now wouldn't changing value references to the soft
    ones is such a good idea? Consider java.lang.ref.Reference -- a base
    class for SoftReference. I counted 5 data members in it. Therefore,
    redesigning a map with soft references would blow up the memory, the
    effect being more significant for maps containing simple key/value
    pairs. Quite odd isn't it solving memory problem by demanding more
    memory?-)
     
    Tegiri Nenashi, Jul 9, 2008
    #4
  5. Tegiri Nenashi

    Tom Anderson Guest

    On Wed, 9 Jul 2008, Tegiri Nenashi wrote:

    > On Jul 9, 11:11 am, Joshua Cranmer <> wrote:
    >> Tegiri Nenashi wrote:
    >>> I'm not sure I ever saw a convincing example. Let's consider the two
    >>> frequented in the literature.

    >>
    >> The most common example, which you seem to have missed is caching, which
    >> is what SoftReferences are used for.

    >
    > OK, here is one more idea I don't understand. Suppose we have a global
    > map that caches up some things and which one can grow to overwhelm the
    > available memory. Now wouldn't changing value references to the soft
    > ones is such a good idea? Consider java.lang.ref.Reference -- a base
    > class for SoftReference. I counted 5 data members in it. Therefore,
    > redesigning a map with soft references would blow up the memory, the
    > effect being more significant for maps containing simple key/value
    > pairs. Quite odd isn't it solving memory problem by demanding more
    > memory?-)


    You're quite right that using SoftReferences will increase the amount of
    memory used to store a given number of objects. But in return, you get the
    ability to automatically discard objects when memory is in short supply.
    That may be a useful tradeoff.

    I would hesitate to use SoftReferences for any object that's about the
    same size as the SoftReference itself. I think they're more useful for
    large objects, for example parsed XML documents or images. There, a
    handful of extra words to buy easier memory management is a good tradeoff.

    tom

    --
    Not all legislation can be eye-catching, and it is important that the
    desire to achieve the headlines does not mean that small but useful
    measures are crowded out of the legislative programme. -- Select Committee
    on Transport
     
    Tom Anderson, Jul 9, 2008
    #5
  6. Tegiri Nenashi wrote:
    > OK, here is one more idea I don't understand. Suppose we have a global
    > map that caches up some things and which one can grow to overwhelm the
    > available memory. Now wouldn't changing value references to the soft
    > ones is such a good idea? Consider java.lang.ref.Reference -- a base
    > class for SoftReference. I counted 5 data members in it. Therefore,
    > redesigning a map with soft references would blow up the memory, the
    > effect being more significant for maps containing simple key/value
    > pairs. Quite odd isn't it solving memory problem by demanding more
    > memory?-)


    The memory overhead of soft, weak, or phantom references is on the order
    of bytes. Caches will most likely hold objects consuming hundreds of
    kilobytes or more.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Jul 9, 2008
    #6
  7. On Jul 9, 12:18 pm, Tom Anderson <> wrote:
    > You're quite right that using SoftReferences will increase the amount of
    > memory used to store a given number of objects. But in return, you get the
    > ability to automatically discard objects when memory is in short supply.
    > That may be a useful tradeoff.
    >
    > I would hesitate to use SoftReferences for any object that's about the
    > same size as the SoftReference itself. I think they're more useful for
    > large objects, for example parsed XML documents or images. There, a
    > handful of extra words to buy easier memory management is a good tradeoff.


    Why not much simpler solution: a listener on low memory event that
    would just clean up all the cache?
     
    Tegiri Nenashi, Jul 9, 2008
    #7
  8. On Jul 9, 12:25 pm, Joshua Cranmer <> wrote:
    > Tegiri Nenashi wrote:
    > > OK, here is one more idea I don't understand. Suppose we have a global
    > > map that caches up some things and which one can grow to overwhelm the
    > > available memory. Now wouldn't changing value references to the soft
    > > ones is such a good idea? Consider java.lang.ref.Reference -- a base
    > > class for SoftReference. I counted 5 data members in it. Therefore,
    > > redesigning a map with soft references would blow up the memory, the
    > > effect being more significant for maps containing simple key/value
    > > pairs. Quite odd isn't it solving memory problem by demanding more
    > > memory?-)

    >
    > The memory overhead of soft, weak, or phantom references is on the order
    > of bytes. Caches will most likely hold objects consuming hundreds of
    > kilobytes or more.


    To repeat, why not sweep up everything from the cache, triggered by
    low memory event? Or you imply that fancy references can be tuned to
    provide a specific policy to my cache (e.g. purge 90% of LRU stuff)?
     
    Tegiri Nenashi, Jul 9, 2008
    #8
  9. On Jul 9, 11:49 am, jolz <> wrote:
    > > I'm still not sure when one would use WeakReferences

    >
    > I'v never had to use myself, but there was exactly one time when I was
    > really surprised that library I'm using does't use WeakHashMap.


    How does WeakHashMap is supposed to work? According to javadoc

    * An entry in a <tt>WeakHashMap</tt> will automatically be removed
    when
    * its key is no longer in ordinary use...

    My estimate is that more than half of the Map usages are with the
    String keys. Now what does it mean the string being no longer in
    ordinary use, does it mean nobody refers to literal "abc" anymore so
    that the <"abc",...> pair can be removed from the hash? What is the
    point to keep the hash map entry if my code still holds reference to
    the key?
     
    Tegiri Nenashi, Jul 9, 2008
    #9
  10. Tegiri Nenashi wrote:
    > To repeat, why not sweep up everything from the cache, triggered by
    > low memory event? Or you imply that fancy references can be tuned to
    > provide a specific policy to my cache (e.g. purge 90% of LRU stuff)?


    First off, I believe SoftReference has been available since the first
    version of Java, notably before Java gained the ability to notify you on
    low memory.

    Secondly, the low memory notification event comes with this warning:
    The memory usage monitoring mechanism is intended for load-balancing or
    workload distribution use. For example, an application would stop
    receiving any new workload when its memory usage exceeds a certain
    threshold. It is not intended for an application to detect and recover
    from a low memory condition.

    Reasoning why becomes quickly evident:
    There is no guarantee about when the MemoryMXBean will emit a threshold
    notification and when the notification will be delivered.

    Finally, one will generally find that the garbage collector is smarter
    about memory collection than you are. Leaving it to the garbage
    collector to decide when the SoftReference is taking up too much memory
    is probably better than leaving it to you, especially because the
    garbage collector has inside knowledge.

    So, in short, relying on low memory notifications forces you to rely on
    newer versions, is flaky at best since it relies on notifications
    happening at ill-defined moments, and assumes that you really know
    better than the GC.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Jul 9, 2008
    #10
  11. On Jul 9, 12:35 pm, Joshua Cranmer <> wrote:
    > Tegiri Nenashi wrote:
    > > To repeat, why not sweep up everything from the cache, triggered by
    > > low memory event? Or you imply that fancy references can be tuned to
    > > provide a specific policy to my cache (e.g. purge 90% of LRU stuff)?

    >
    > First off, I believe SoftReference has been available since the first
    > version of Java, notably before Java gained the ability to notify you on
    > low memory.


    What this point is supposed to demonstrate? How immature Java
    designers are?

    > Secondly, the low memory notification event comes with this warning:
    > The memory usage monitoring mechanism is intended for load-balancing or
    > workload distribution use. For example, an application would stop
    > receiving any new workload when its memory usage exceeds a certain
    > threshold. It is not intended for an application to detect and recover
    > from a low memory condition.


    Well, I refuse possibly to believe that it is impossible to design a
    modestly reliable system of low memory notification.

    > Reasoning why becomes quickly evident:
    > There is no guarantee about when the MemoryMXBean will emit a threshold
    > notification and when the notification will be delivered.


    You have to realize that memory limitation is a physical
    implementation artifact, and there is nothing fundamental about it.
    Therefore, there is little point making guarantees and inventing
    arbitrary constraints on how this event is emitted or delivered.

    > Finally, one will generally find that the garbage collector is smarter
    > about memory collection than you are. Leaving it to the garbage
    > collector to decide when the SoftReference is taking up too much memory
    > is probably better than leaving it to you, especially because the
    > garbage collector has inside knowledge.


    So? I'm impressed with ingenuity and clarity of mark-and-sweep based
    GC. Ditto for the streamlined reference design (compared to the
    pointer/reference C++ mess). And now you come back and tell me that we
    need more kinds of those pointer thingies?

    > So, in short, relying on low memory notifications forces you to rely on
    > newer versions, is flaky at best since it relies on notifications
    > happening at ill-defined moments, and assumes that you really know
    > better than the GC.


    Well, as someone eloquently put it: "There is no dumber thing than a
    smart pointer". This whole fancy references endeavor made me
    appreciate it a little more.
     
    Tegiri Nenashi, Jul 9, 2008
    #11
  12. Tegiri Nenashi

    EJP Guest

    Joshua Cranmer wrote:
    > First off, I believe SoftReference has been available since the first
    > version of Java, notably before Java gained the ability to notify you on
    > low memory.


    @since 1.2 actually, but that's sufficiently long ago now ;-)
     
    EJP, Jul 10, 2008
    #12
  13. Joshua Cranmer wrote:
    > Tegiri Nenashi wrote:
    >> I'm not sure I ever saw a convincing example. Let's consider the
    >> two
    >> frequented in the literature.

    >
    > I'm still not sure when one would use WeakReferences, but
    > SoftReferences have good uses.


    Here's a simple case for a WeakReference:

    G is a GUI widget that displays the state of some object O. In order
    to stay up-to-date, G subscribes to events triggered when O changes.
    Without WeakReferences, this means that O has a hard link to G, tying
    G's lifetime to O's. Since the window containing G should be free to
    go away and be cleaned up, this is unfortunate. There are two ways to
    improve this:

    1. G can be careful to unsubscribing when its parent window exits.
    2. G can subscribe via a WeakReference to itself.

    2 involves less bookkeeping, and so is more robust. This isn't a
    kludge, really. If G is interested in O's state, that should mean
    that G refers to O. The fact that O winds up referring to G is purely
    implementation. That we can implement it such that O will not refer
    to G is a good thing.
     
    Mike Schilling, Jul 10, 2008
    #13
  14. Tegiri Nenashi wrote:
    > I'm not sure I ever saw a convincing example. Let's consider the two
    > frequented in the literature.
    >
    > 1. HashMap (why not other collection?). I understand that if a
    > reference to HashMap is still reachable, the whole HashMap and their
    > references would be reachable, if the reference to HashMap is gone,
    > the referred objects (keys and values) would decrement their counts
    > (although counts don't really matter in mark-and-sweep method) . If
    > a
    > key and a value is not reference anywhere else, then key is supposed
    > to be marked as garbaged collected. Finally, with the key holding no
    > references, it is value that is marked to be garbage collected as
    > well.


    You do realize that the key is also referenced by the hash map
    internals (to be specific, the entry that contains the key is in some
    hash chain.) .Absent some mechanism like weak references, the key
    can't be collection unless it's explicitly removed from the map.
     
    Mike Schilling, Jul 10, 2008
    #14
  15. On Jul 10, 1:21 am, "Mike Schilling" <>
    wrote:
    > Tegiri Nenashi wrote:
    > > I'm not sure I ever saw a convincing example. Let's consider the two
    > > frequented in the literature.

    >
    > > 1. HashMap (why not other collection?). I understand that if a
    > > reference to HashMap is still reachable, the whole HashMap and their
    > > references would be reachable, if the reference to HashMap is gone,
    > > the referred objects (keys and values) would decrement their counts
    > > (although counts don't really matter in mark-and-sweep method) . If
    > > a
    > > key and a value is not reference anywhere else, then key is supposed
    > > to be marked as garbaged collected. Finally, with the key holding no
    > > references, it is value that is marked to be garbage collected as
    > > well.

    >
    > You do realize that the key is also referenced by the hash map
    > internals (to be specific, the entry that contains the key is in some
    > hash chain.)  .Absent some mechanism like weak references, the key
    > can't be collection unless it's explicitly removed from the map.


    Is "hash internals" some global structure? Otherwise, I don't see why
    a whole subgraph of HashMap references -- no matter how messy it is --
    won't be marked for deletion when the link to the root is deleted.
     
    Tegiri Nenashi, Jul 10, 2008
    #15
  16. On Jul 10, 1:21 am, "Mike Schilling" <>
    wrote:
    > Tegiri Nenashi wrote:
    > > I'm not sure I ever saw a convincing example. Let's consider the two
    > > frequented in the literature.

    >
    > > 1. HashMap (why not other collection?). I understand that if a
    > > reference to HashMap is still reachable, the whole HashMap and their
    > > references would be reachable, if the reference to HashMap is gone,
    > > the referred objects (keys and values) would decrement their counts
    > > (although counts don't really matter in mark-and-sweep method) . If
    > > a
    > > key and a value is not reference anywhere else, then key is supposed
    > > to be marked as garbaged collected. Finally, with the key holding no
    > > references, it is value that is marked to be garbage collected as
    > > well.

    >
    > You do realize that the key is also referenced by the hash map
    > internals (to be specific, the entry that contains the key is in some
    > hash chain.)  .Absent some mechanism like weak references, the key
    > can't be collection unless it's explicitly removed from the map.


    Ok, let's be more specific.

    class HashMap {
    Entry[] table;
    ...
    }

    No problem here, I assume if there is no references to HashMap all the
    rederences to Entry would be marked for deletion.

    class Entry<K,V> {
    K key;
    V value;
    Entry<K,V> next;
    }

    Next if the Entry object is marked for deletion, then key, value, and
    the next entry in the chain are maked as well.

    So, there is nothing specific about the key at all!
     
    Tegiri Nenashi, Jul 10, 2008
    #16
  17. Tegiri Nenashi wrote:
    > On Jul 10, 1:21 am, "Mike Schilling" <>
    > wrote:
    >> Tegiri Nenashi wrote:
    >>> I'm not sure I ever saw a convincing example. Let's consider the
    >>> two
    >>> frequented in the literature.

    >>
    >>> 1. HashMap (why not other collection?). I understand that if a
    >>> reference to HashMap is still reachable, the whole HashMap and
    >>> their
    >>> references would be reachable, if the reference to HashMap is
    >>> gone,
    >>> the referred objects (keys and values) would decrement their
    >>> counts
    >>> (although counts don't really matter in mark-and-sweep method) .
    >>> If
    >>> a
    >>> key and a value is not reference anywhere else, then key is
    >>> supposed
    >>> to be marked as garbaged collected. Finally, with the key holding
    >>> no
    >>> references, it is value that is marked to be garbage collected as
    >>> well.

    >>
    >> You do realize that the key is also referenced by the hash map
    >> internals (to be specific, the entry that contains the key is in
    >> some
    >> hash chain.) .Absent some mechanism like weak references, the key
    >> can't be collection unless it's explicitly removed from the map.

    >
    > Is "hash internals" some global structure?


    The internals of the HashMap implementation

    > Otherwise, I don't see why
    > a whole subgraph of HashMap references -- no matter how messy it
    > is --
    > won't be marked for deletion when the link to the root is deleted.


    Read up a bit on how HashMaps are implemented and you'll begin to
    understand it. If you can design an alternate implementation that
    allows the sort of collection you just described, I'd be very
    interested in seeing it.
     
    Mike Schilling, Jul 10, 2008
    #17
  18. On Jul 10, 1:17 am, "Mike Schilling" <>
    wrote:
    > Joshua Cranmer wrote:
    > > Tegiri Nenashi wrote:
    > >> I'm not sure I ever saw a convincing example. Let's consider the
    > >> two
    > >> frequented in the literature.

    >
    > > I'm still not sure when one would use WeakReferences, but
    > > SoftReferences have good uses.

    >
    > Here's a simple case for a WeakReference:
    >
    > G is a GUI widget that displays the state of some object O.  In order
    > to stay up-to-date, G subscribes to events triggered when O changes.
    > Without WeakReferences, this means that O has a hard link to G, tying
    > G's lifetime to O's.  Since the window containing G should be free to
    > go away and be cleaned up, this is unfortunate.  There are two ways to
    > improve this:
    >
    > 1. G can be careful to unsubscribing when its parent window exits.
    > 2. G can subscribe via a WeakReference to itself.
    >
    > 2 involves less bookkeeping, and so is more robust.  This isn't a
    > kludge, really.  If G is interested in O's state, that should mean
    > that G refers to O.  The fact that O winds up referring to G is purely
    > implementation.  That we can implement it such that O will not refer
    > to G is a good thing.


    To quote another guy, who is mathematician, computer buffs like to
    complicate everything. Let see what is important in your example. You
    have a parent widget, child widget and an external data object that
    child references. No matter how complicated references subgraph for
    the system of all the three objects in our picture are, this whole
    hairball of references would be disconnected from the outside world as
    soon as parent goes away, no?
     
    Tegiri Nenashi, Jul 10, 2008
    #18
  19. Tegiri Nenashi

    jolz Guest

    > My estimate is that more than half of the Map usages are with the
    > String keys. Now what does it mean the string being no longer in
    > ordinary use, does it mean nobody refers to literal "abc" anymore so
    > that the <"abc",...> pair can be removed from the hash?


    String is almost like any other object. If there is no reference to the
    object, it is removed. For example:
    WeakHashMap<String, String> m = new WeakHashMap<String, String>();
    m.put(new String("1"), "1");
    while (true) {
    System.gc();
    if (m.size() == 0) {
    break;
    }
    }

    > What is the
    > point to keep the hash map entry if my code still holds reference to
    > the key?


    If yor code still holds the reference, object isn't weakly reachable and
    won't be removed from WeakHashMap. You may remove it manually if you want.
     
    jolz, Jul 10, 2008
    #19
  20. Tegiri Nenashi wrote:
    > To quote another guy, who is mathematician, computer buffs like to
    > complicate everything. Let see what is important in your example. You
    > have a parent widget, child widget and an external data object that
    > child references. No matter how complicated references subgraph for
    > the system of all the three objects in our picture are, this whole
    > hairball of references would be disconnected from the outside world as
    > soon as parent goes away, no?


    No. The graph looks like this:

    Window <-> Widget <- Data Manager

    The implication is that the Data Manager is going to be around for a
    long time; let's say it was a TCP connection manager and our widget is
    popping up in a network monitor window. Obviously, you'd want the Window
    and Widget to be reclaimable as soon as you close the window, but the
    Data Manager will refuse to let them be reclaimed since its held to for
    the entirety of the application.

    If you open up a lot of windows... MEMORY LEAK!

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Jul 10, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kuan Zhou
    Replies:
    1
    Views:
    5,212
    Paul Uiterlinden
    Jan 24, 2005
  2. Nicholas Zigarovich

    Strange behavior with weak references

    Nicholas Zigarovich, Sep 2, 2003, in forum: Java
    Replies:
    0
    Views:
    380
    Nicholas Zigarovich
    Sep 2, 2003
  3. Mark M
    Replies:
    16
    Views:
    740
    Chris Uppal
    Mar 5, 2004
  4. Lars Willich
    Replies:
    13
    Views:
    915
    Ian Shef
    Oct 23, 2007
  5. ade0
    Replies:
    1
    Views:
    317
    Gunnar Hjalmarsson
    Apr 6, 2005
Loading...

Share This Page