weakreferences (java.lang.ref and more)
DESCRIPTION
One of the most overlooked features of Java and programming generally, is WeakReferences. Here you can find a walkthrough of java.lang.ref and similar options in other languages with suggestions of possible uses.TRANSCRIPT
java.lang.refSince Java 1.2
... references?
● A reference is, as its name suggests, what you use to point to (reference) an object somewhere else in the memory.
● You use it all the time!String s = “string”; // s is a reference
There are more?
● Probably, all our life, we’ve been using only one type of references; strong references.
● Object o = new Object(); As long as you keep o to your side, the object it references stays in memory.
There are more?
● There are more levels of “strength or reachability” for references.○ Soft○ Weak○ Phantom
● You can get these by using package java.lang.ref.
How to?
● You use them as you use the usual strong reference, but use them for special purposes.
● The GC handles them as it handles the strong references. So it’s done for you and you can’t add to it or extend it.
Reference<T>
● Constructor: Reference(T referent)● T get()● void clear ()
● That’s it. Once you initialize it, you can’t change the “referent”. Clearing is your only option.
Softly reachable..
● The next level after strong references is soft references.
● A softly reachable object is an object that has no strong references, but has soft ones.
● Object o = new Object();SoftReference<Object> softRef = new SoftReference<Object>(o);o = null; // o is now softly reachable
Softly reachable… so?
● Important point about references is when the GC decides to reclaim referents.
● It’s guaranteed to live till an OutOfMemoryError is thrown, then there’s no guarantee.
● Sounds good for simple caches.● Some JRE implementations start collection
with the oldest objects.
Weak references
● It’s weakly reachable when there are no strong or soft references to it, and it has weak references to it.
● Once the object is weakly reachable, it’s eligible for finalization at once.
Weak references
● java.util.WeakHashMap
● References the keys weakly and the values strongly. Once the key goes weak, its record is removed from the map.
Phantom references
● No strong. No soft. No weak. And some phantom references to the object.
● If the object is phantomly reachable, it’s dead! So get() returns null.
● In fact, it always returns null.
Phantom references
● Sounds unuseful!● The only value is to get notified of the object
getting in that level. i.e. get notified that it’s really dead, to do post-mortem stuff.
● P.S. finalize() isn’t immune to fooling around. You can resurrect the object from death there.
ReferenceQueue<? super T>
● Nothing really! It just tells you when the objects reach registered reachability levels.
● If the object moves from strongly reachable to softly reachable, you’ll get the call
ReferenceQueue
● Reference(T referent, ReferenceQueue<? super T> queue)
● Reference<? extends T> poll() // doesn’t block● remove(), remove(long timeOut) // blocks
● As mentioned before, phantom references are only good with queues. However, weak and soft references are good with it too.
Ruby - WeakRef
● Inherits from Delegator -> You can deal with it the same way you deal with the object.
● Uses object ID to keep track
● Raises an exception when referenced after being collected
Python - weakref
● weakref.ref(obj [,callback])● Also WeakKeyDictionary and
WeakValueDictionary● Not all objects can be weakly referenced.● Some built-in types don’t support weak
references unless subclassed.○ str can never be
● Good to avoid cyclic references (before 2.0)
Python - weakref
● weakref.getweakrefcount(obj)● weakref.proxy(object [,callback]) //
Alternative to subclassing
● Extension types can be made to support weak references
Objective-C
● Reference counting and ARC -> NOT GC
● strong vs weak @property becomes nil automatically
● Avoid cyclic strong references
Objective-C
● NSMapTable: Dictionary (weak keys, weak values, both)
● NSHashTable: Set● NSPointerArray:Array
● NSPointerFunctions
C++11
● Use std::shared_ptr instead of a regular pointer.
● Use std::weak_ptr with the shared pointer● There are other libraries for pre C++11
Uses
● Simple Caching: Storing the big object in memory until everybody stops using it. ○ Java’s SoftReference. Weak references won’t be
much useful for that● Listeners: Keeps notifying objects until they’
re out of reach. ○ Problem with anonymous objects in Java.
Uses● Associating data with various objects “meta-
data storing”: Doesn’t make sense to override○ Store data specific to a thread○ Store data specific to a view object; like a tag or a
serial○ Store data specific to a resource object; like a file
Uses
● Canonicalized mapping○ Store one reference for the same objects and
remove them when nobody needs them anymore.Map employeesByID = new HashMap<String, WeakReference<Employee>(); // Maps employee IDs to weak references of Employee objects retrieved from DB
Be Careful
● Weak maps usually check references for equality.
String s1 = “Hello!”;String s2 = new String([‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘!’]);strongMap.put(s1, value); weakMap.put(s1, value);strongMap.contains(s2) //true;weakMap.contains(s2) // false;
Be Careful
● “Premature optimization is the root of all evil”○ Weak references and their dependencies are great
for special uses, not everything.
References● Javadoc● Understanding Weak References● Getting to know the Ruby Standard Library - WeakRef● docs.python.org● Canonicalized Mapping● Weak Object Pools with WeakHashMap
● Some others I can’t remember.