Thursday, November 29, 2007

Java: Understanding Weak References

The other day i was reading programming at reddit and stumbled on this article:
Understanding Weak References which was a good read but i still had some questions, so i turned to Java Developer Forums for help. I didnt get flamed! (much). What i got was a very good response from a user named kdgregory which is note-to-dogself worthy.

My questions are in blue boxes:
If weak references are great at stopping leaks, why not use them all the time?

They're great at stopping leaks in the situation where you're attaching data to an object that (should) have a limited lifetime. If you used a regular map (most likely an IdentityHashMap), you'd be creating a strong reference to the object via the map, so it would never be collected, even when there are no other references to it (I call this a leak, other people don't).

For example, ThreadLocal uses weak references, because they'll be cleared when the thread ends.

ObjectOutputStream should use weak references (and a changed protocol) so that it can be used in long-running conversations without constantly calling reset(). But it doesn't.

"WeakHashMap works exactly like HashMap, except that the keys (not the values!) are referred to using weak references."
  • does this imply that hashmap stores values in weak refs, if so, why?
  • should i use WeakHashMap for tasks where i will have another reference to objects i put into the map. ie i dont put my only ref into this map?

No, HashMap doesn't use weak references for either key or value. The author's wording (and for that matter, the JDK JavaDoc wording) is a little misleading.

One typical use for weak references is in a canonicalizing map to reduce memory consumption with duplicated data. With such a map, you would store an object as both key and value, and retrieve the canonical value when presented with an arbitrary key -- think String.intern(). However, you can't use WeakHashMap to do this without wrapping the value in a weak reference also.

When do i not use weak references ?

Most of the time. Any reference object means that you have to access your original object in two steps (have to call get() on the reference) rather than just one. And normally, you'd know the lifetime of your objects.

1 comment:

  1. Finally got the references article up ... and in fact, finally got the site semi-working.

    http://www.kdgregory.com/index.php?page=java.refobj

    Turns out I was wrong about why ThreadLocal uses WeakReferences. I spent some time looking through the code, and it turns out the Thread holds a WeakReference to the ThreadLocal. As best I can tell, it's used to clean up if the thread-local gets collected (either it's in an instance that gets collected, or it's a static held by a classloader that gets collected).

    ReplyDelete