Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Excessive memory leaks can lead to memory exhaustion and denial of service (DoS) and must be avoided . For more information, (see rule MSC05-J. Do not exhaust heap space for more information).

Noncompliant Code Example (Off-by-One Programming Error)

...

This compliant solution corrects the mistake by changing the loop condition to n >= 0. It also wraps the cleanup code in a finally block , so that it still executes even if the interim code throws an exception.

...

Prefer the use of standard language semantics where possible. This compliant solution uses the vector.clear() method, which removes all elements.:

Code Block
bgColor#ccccff
public void useVector(int count) { 	
  try {
    for (int n = 0; n < count; n++) {
      vector.add(Integer.toString(n));
    }
    // ...
  } finally {
    vector.clear(); // Clear the vector
  }
}

...

This noncompliant code example declares and allocates a HashMap instance field that is used only in the doSomething() method.:

Code Block
bgColor#FFCCCC
public class Storer {
  private HashMap<Integer,String> hm = new HashMap<Integer, String>();
  
  private void doSomething() {
    // hm is used only here and never referenced again
    hm.put(1, "java");
    // ...
  }
}

...

This noncompliant code example, known as the Lapsed Listener [Goetz 2005a], demonstrates unintentional object retention. The button continues to hold a reference of the reader object after completion of the readSomething() method, even though the reader object is never used again. Consequently, the garbage collector cannot collect the reader object. A similar problem occurs with inner classes because they hold an implicit reference to the enclosing class.

...

This noncompliant code example attempts to remove the reader through use of the removeActionListener() method.:

Code Block
bgColor#FFCCCC
Reader reader = new Reader();
button.addActionListener(reader);
try {
  reader.readSomething();  // Can skip next line of code
  // Dereferenced, but control flow can change
  button.removeActionListener(reader);  
} catch (IOException e) { 
  // Forward to handler 
}

...

This compliant solution uses a finally block to ensure that the reader object's reference is removed.:

Code Block
bgColor#ccccff
Reader reader = new Reader();
button.addActionListener(reader);
try {
  reader.readSomething();
} catch (IOException e) { 
  // Handle exception 
} finally {
  button.removeActionListener(reader);  // Always executed
}

...

This noncompliant code example implements a stack data structure [Bloch 2008] that continues to hold references to elements after they have been popped off the stack.:

Code Block
bgColor#FFCCCC
public class Stack {
  private Object[] elements;
  private int size = 0;

  public Stack(int initialCapacity) {
    this.elements = new Object[initialCapacity];
  }

  public void push(Object e) {
    ensureCapacity();
    elements[size++] = e;
  }

  public Object pop() { // This method causes memory leaks
    if (size == 0) {
      throw new EmptyStackException();
    }
    return elements[--size];
  }

  /*
   * Ensure space for at least one more element, roughly
   * doubling the capacity each time the array needs to grow.
   */
  private void ensureCapacity() {
    if (elements.length == size) {
      Object[] oldElements = elements;
      elements = new Object[2 * elements.length + 1];
      System.arraycopy(oldElements, 0, elements, 0, size);
    }
  }
}

...

This compliant solution assigns null to all obsolete references.:

Code Block
bgColor#ccccff
public Object pop() {
  if (size == 0) {
    throw new EmptyStackException(); // Ensures object consistency
  }
  Object result = elements[--size];
  elements[size] = null; // Eliminate obsolete reference
  return result;
} 

...

Although these examples appear trivial and do not represent significant problems in production code, obsolete references remain a concern when dealing with data structures such as hash tables containing many large records. It is prudent to assign null to array-like custom data structures; doing so with individual objects references or local variables is unnecessary because the garbage collector handles these cases automatically [Commes 2007].

Noncompliant Code Example (Strong References)

A common variation of the obsolete object fallacy is the unintentional retention of objects in collections such as maps. In this noncompliant code example, a server maintains temporary metadata about all committed secure connections.:

Code Block
bgColor#FFCCCC
class HashMetaData {
  private Map<SSLSocket, InetAddress> m = Collections.synchronizedMap(
      new HashMap<SSLSocket, InetAddress>());

  public void storeTempConnection(SSLSocket sock, InetAddress ip) {
    m.put(sock, ip);  
  }

  public void removeTempConnection(SSLSocket sock) {
    m.remove(sock);  
  }	
}

...

This compliant solution uses weak references to allow timely garbage collection.:

Code Block
bgColor#ccccff
// ...
  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 20062014], 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 2005b].

...

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 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 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
bgColor#ccccff
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.operation, the SoftReference object in the hash map is also garbage-collected:

Code Block
bgColor#ccccff
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 where in which efficient memory usage is critical, and soft references should be preferred in applications that rely heavily on caching.

...

Memory leaks in Java applications may be exploited in a DoS attack attack.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC04-J

low

unlikely

high

P1

L3

Low

Unlikely

High

P1

L3

Automated Detection

ToolVersionCheckerDescription
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.MSC04.LEAKSEnsure resources are deallocated

Related Guidelines

ISO/IEC TR 24772:2010

Memory Leak [XYL]

MITRE CWE

CWE-401

.

, Improper

release

Release of

memory before removing last reference

Memory before Removing Last Reference ("

memory leak

Memory Leak")

Bibliography

[API

2006

2014]

Class Vector

,


Class WeakReference

[Bloch 2008]

Item 6

. Eliminate obsolete object references

[Goetz 2005b]

Memory Leaks with Global Maps; Reference Queues

, "Eliminate Obsolete Object References"

[Commes 2007]

"Memory Leak Avoidance"

[Goetz 2005a]

"Lapsed Listeners

"

[Gupta 2005]

 

...



...

Image Modified Image Modified Image Modified