...
Code Block | ||
---|---|---|
| ||
// ... private Map<SSLSocket, InetAddress> m = Collections.synchronizedMap( new WeakHashMap<SSLSocket, InetAddress>() ); // ... |
Strong references prevent the garbage collector from reclaiming objects that are stored inside container objects, such as in a Map
. According to the Java API [API 2014], weak reference objects "do not prevent their referents from being made finalizable, finalized, and then reclaimed."
...
Simply facilitating garbage collection of unneeded objects through use of weak references is insufficient. Programs must also prune the recording 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 2005bThe 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-collectedReference queues provide notifications when a referent is garbage-collected. When the referent is garbage-collected, the HashMap
continues to strongly reference both the WeakReference
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 WeakReference
SoftReference
object to the reference queue. The WeakReference
SoftReference
object remains in the reference queue until some operation is performed on the queue (such as a putpoll()
or remove()
). After such an operation, the WeakReference
SoftReference
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 = new WeakReference<SSLSocket>(sock, queue);
// 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);
}
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)
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 = new SoftReference<SSLSocket>(sock, queue); 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) { deleted, no m.remove(sock); } 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.
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| BDCERT.RESMSC04.LEAKS | ImplementedEnsure resources are deallocated |
Related Guidelines
Memory Leak [XYL] | |
CWE-401, Improper Release of Memory before Removing Last Reference ("Memory Leak") |
...
[API 2014] | |||
Item 6, "Eliminate Obsolete Object References" | |||
"Memory Leak Avoidance" | |||
"Lapsed Listeners" | "Memory Leaks with Global Maps" | ||
...