...
Simply facilitating garbage collection of unneeded objects through use of weak references is insufficient. Programs must also prune the data structure so that additional live entries can be accommodated. One pruning technique is to call the get()
method of WeakHashMap
and remove any entry that corresponds to a null
return value (polling). Use of reference queues is a more efficient method [Goetz 2005b].
Compliant Solution (Reference Queue)
Reference queues provide notifications when a referent is garbage-collected. When the referent is garbage-collected, the HashMap
continues to strongly reference both the WeakReference
object and the corresponding map value (for each entry in the HashMap
).
When the garbage collector clears the reference to an object, it adds the corresponding WeakReference
object to the reference queue. The WeakReference
object remains in the reference queue until some operation is performed on the queue (such as a put()
or remove()
). After such an operation, the WeakReference
object in the hash map is also garbage-collected. Alternatively, this two-step procedure can be carried out manually by using the following code:
Code Block | ||
---|---|---|
| ||
class HashMetaData {
private Map<WeakReference<SSLSocket>, InetAddress> m =
Collections.synchronizedMap(
new HashMap<WeakReference<SSLSocket>, InetAddress>());
ReferenceQueue queue = new ReferenceQueue();
public void storeTempConnection(SSLSocket sock, InetAddress ip) {
WeakReference<SSLSocket> wr;
// Poll for dead entries before adding more
while ((wr = (WeakReference) queue.poll()) != null) {
// Removes the WeakReference object and the value (not the referent)
m.remove(wr);
}
wr = new WeakReference<SSLSocket>(sock, queue);
m.put(wr, ip);
}
public void removeTempConnection(SSLSocket sock) {
m.remove(sock);
}
}
|
Note that the two-argument constructor of WeakReference
takes a Queue
argument and must be used to perform direct queue processing. Dead entries should be pruned prior to insertion.
Compliant Solution (Soft References)
However, the implementation of WeakHashMap
in Java 7 includes a reference queue to efficiently remove entries that correspond to a null pointer value [https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/WeakHashMap.java].
Compliant Solution (Soft References)
Use of soft references is also permitted. Soft references guarantee that the referent will be reclaimed before an OutOfMemoryError
occurs and also that the referent will remain live until memory begins to run out.
Reference queues provide notifications when a referent is garbage-collected. When the referent is garbage-collected, the HashMap
continues to strongly reference both the SoftReference
object and the corresponding map value (for each entry in the HashMap
).
When the garbage collector clears the reference to an object, it adds the corresponding SoftReference
object to the reference queue. The SoftReference
object remains in the reference queue until some operation is performed on the queue (such as a put()
or remove()
). After such an operation, the SoftReference
object in the hash map is also garbage-collected:Use of soft references is also permitted. Soft references guarantee that the referent will be reclaimed before an OutOfMemoryError
occurs and also that the referent will remain live until memory begins to run out.
Code Block | ||
---|---|---|
| ||
class HashMetaData { private Map<SoftReference<SSLSocket>, InetAddress> m = Collections.synchronizedMap( new HashMap<SoftReference<SSLSocket>, InetAddress>()); ReferenceQueue queue = new ReferenceQueue(); public void storeTempConnection(SSLSocket sock, InetAddress ip) { SoftReference<SSLSocket> sr; while ((sr = (SoftReference) queue.poll()) != null) { // Removes the WeakReference object and the value (not the referent) m.remove(sr); } sr = new SoftReference<SSLSocket>(sock, queue); m.put(sr, ip); } public void removeTempConnection(SSLSocket sock) { m.remove(sockput(sr, ip); } } } // removeTempConnection() deleted, no longer necessary } |
Note that the two-argument constructor of SoftReference
takes a Queue
argument and must be used to perform direct queue processing. Dead entries should be pruned prior to insertion.
Weak references are garbage-collected more aggressively than soft references. Consequently, weak references should be preferred in applications in which efficient memory usage is critical, and soft references should be preferred in applications that rely heavily on caching.
...