Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
Programming errors           Even though Java supports memory management through can prevent garbage collection, there are innumerable possibilities of introducingobjects memorythat leaksare asno alonger resultrelevant ofto programmingprogram errorsoperation. Furthermore,The the garbage collector collects only the unreachable objects; andconsequently, not those that are still reachable. The the presence of reachable objects that remain unused indicates memory mismanagement.

Depending on program scale and available memory, Consumption of all available heap space can cause an {{OutOfMemoryError}} may result when the heap space runs out. This usually results in program failure, which usually results in program failure. Memory leaks afford adversaries with a potentially exploitable denial of service attack, and consequently are forbidden.

h2. Noncompliant Code Example (Off-By-One Programming Error)

This noncompliant code example shows a leaking {{Vector}} object. The memory leak quickly exhausts the heap space as the condition for removing the {{vector}} element is mistakenly written as {{n > 0}} instead of {{n >= 0}}. As a result, in every iteration, the method leaks one {{vector}} element.  Consequently, the method leaks one {{vector}} per invocation, and quickly exhausts the available heap space.

{code:bgColor=#FFCCCC}
public class Leak {
  static Vector vector = new Vector();

  public void useVector(int count) { 	
    for (int n = 0; n < count; n++) {
      vector.add(Integer.toString(n));
    }
    // ...
    for (int n = count - 1; n > 0; n--) { // Free the memory
      vector.removeElementAt(n);
    }	
  }

  public static void main(String[] args) throws IOException {
    Leak le = new Leak();
    int i = 1;
    while(true) {
      System.out.println("Iteration: " + i);
      le.useVector(1);
      i++;
    }
  }
}
{code} 

h2. Compliant Solution (1)

This compliant solution corrects the mistake by changing the loop condition to {{n >= 0}}. 

{code:bgColor=#ccccff}
public void useVector(int count) { 	
  for (int n = 0; n < count; n++) {
    vector.add(Integer.toString(n));
  }
  // ...
  for (int n = count - 1; n >= 0; n--) {
    vector.removeElementAt(n);
  }
}	
{code}

h2. Compliant Solution (2)

Prefer the use of standard language semantics where possible, as shown in this compliant solution.

{code:bgColor=#ccccff}
public void useVector(int count) { 	
  for (int n = 0; n < count; n++) {
    vector.add(Integer.toString(n));
  }
  // ...
  while (!vector.isEmpty()){
    vector.removeElementAt(vector.size() - 1);	        	    
  }
}
{code}

h2. Compliant Solution (3)

An alternative way of clearing the {{vector}} is to use the {{vector.clear()}} method. 

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

Likewise,  if a range of elements have to be removed from the {{vector}},Use the {{vector.subList(fromIndex, toIndex).clear()}} method to canremove bea used.subrange Inof theelements contextfrom of this compliant solution,the {{vector}}. Note that the {{fromIndex}} and the {{toIndex}} can both be {{0}} as the {{count}} variable is {{1}} on each iteration \[[API 2006|AA. Bibliography#API 06]\].

h2. Noncompliant Code Example (Non-Local Instance Field)

This noncompliant code example createscode example declares and allocates a {{HashMap}} instance field withinthat the class body but uses it is used only in the {{doSomething()}} method.  

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

ItProgrammers ismay notbe obvioussurprised that itthe {{HashMap}} will continuepersist tofor persistthe asentire longlifetime asof the class {{Storer}}'s instance is alive. 

h2. Compliant Solution (Reduce Scope of Instance Field)

This compliant solution declares the {{HashMap}} as a local variable within the {{doSomething()}} method.

{code:bgColor=#ccccff}
public class Storer {
  private void doSomething() {
    HashMap<Integer,String> hm = new HashMap<Integer,String>();
    hm.put(1,"java");
    // ...
  }
}
{code}

Localizing or confining the instance field to a narrower scope gives the garbageinstance field collectorto a betternarrower chancescope ofsimplifies succeedinggarbage at collecting the object in a timely manner. Short-lived objects are always collected quickly by generational garbage collectorscollection; today's generational garbage collectors perform well with short-lived objects. 

h2. Noncompliant Code Example (Lapsed Listener)

This noncompliant code example, demonstratesknown unintentionalas objectthe retention and is commonly called the _Lapsed Listener__Lapsed Listener_, demonstrates unintentional object retention. The {{button}} continues to hold a reference of the {{reader}} object even after completion of the {{readSomething()}} method, even though the {{reader}} object will never be used again. 

{code:bgColor=#FFCCCC}
public class LapseEvent extends JApplet   {
  JButton button;
  public void init() {
    button = new JButton("Click Me");
    getContentPane().add(button, BorderLayout.CENTER);
    Reader reader = new Reader();
    button.addActionListener(reader);
    try {
      reader.readSomething();
    } catch (IOException e) { 
      // Handle exception 
    }		 
  }
}

class Reader implements ActionListener{
  public void actionPerformed(ActionEvent e)  {
    Toolkit.getDefaultToolkit().beep();
  }
  public void readSomething() throws IOException {
    // Read from file
  }
}
{code}

As a resultConsequently, the garbage collector does notcannot collect the {{reader}} object. A similar problem occurs with inner classes, asbecause they hold an implicit reference to the outerenclosing class.

h2. Noncompliant Code Example (Exception Before Remove)

{mc} Bloch 08 says: The best way to ensure that callbacks are garbage collected promptly is to store only weak references to them, for instance, by storing them only as keys in a WeakHashMap. {mc}

To resolve this problem, a matching pairThis noncompliant code example attempts to remove the reader through use of the {{removeActionListener()}} should be used, as shown below method. 

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

Unfortunately, this is notHowever, the {{removeActionListener}} statement will never executed in the panaceaevent becauseof an exception inthrown by the {{reader.readSomething()}} method can change the control flow in such a way that the {{removeActionListener}} statement is never executed.

h2. Compliant Solution ({{finally}} Block)

This compliant solution uses thea {{finally}} block to ensure that the {{reader}} object's reference is unregistered. 

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

h2. Noncompliant Code Example (Member Object Leaks)

This noncompliant code example implements a {{stack}} data structure \[[Bloch 2008|AA. Bibliography#Bloch 08]\]. The main issue is \] that itcontinues doesto nothold allowreferences theto garbageelements collectorafter tothay deallocatehave memory afterbeen the {{pop}} operation-ed from the stack.  

{code: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);
    }
  }
}
{code} 

The object references are retained even after the element is pop'ed. Such _obsolete references_ areremain notlive, garbageand collected automatically. This can get even more deceitful because none of the objects referenced by the offending object getconsequently cannot be garbage collected. 


h2. Compliant Solution (Assign {{null}} to Elements of Data Structures)

This compliant solution assigns {{null}} values to all obsolete references. 

{code: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;
} 
{code}

The garbage collector can include individual element-objects in its list of objects to free. A {{NullPointerException}} results on subsequent attempts to access the particular object.

WhileAlthough these examples appear trivial, and may notfail to model production scenarios, it is not uncommon to uncover _obsolete references_ remain common when dealing with data structures such as hash tables containing many large-sized records. It is prudent to assign {{null}} to array-like custom data structures,; however, doing so with individual objects or local variables hasis nounnecessary, specificbecause advantages.the The garbage collector is sufficiently equipped to handle handles these cases automatically \[[Commes 2007|AA. Bibliography#Commes 07]\].


h2. Noncompliant Code Example (Strong References)

A common variant of theobsolete aforementioned noncompliant code example objects is the unintentional retention of objects whenin using a {{MapCollections}} orsuch a similaras {{CollectionsMap}} objects. In this noncompliant code example, a server maintains temporary metadata about all committed secure connections it commits to. 

{code: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);  
  }	
}
{code}

Although the metadata is designed to be {{transient}} by nature, it persists even after the particularrelevant socket is closed, until {{removeTempConnection()}} is invoked. Unless someIn the absence of notification logic is installed, it is impossible to determine the bestwhen time to eliminate the object reference by calling call {{removeTempConnection()}}. Moreover, nulling out original objects or referents (Socket connections) proves to beis unwieldy. 


h2. Compliant Solution (Weak References)

This compliant solution uses _weak references_ to mitigateallow timely thegarbage issuecollection. 

{code:bgColor=#ccccff}
// ...
private Map<SSLSocket, InetAddress> m = Collections.synchronizedMap(new WeakHashMap<SSLSocket, InetAddress>());
{code}

Strong references do not allowprevent the garbage collector tofrom reclaim thereclaiming objects that are stored compositely, such as in a {{Map}}. According to the Java API \[[API 2006|AA. Bibliography#API 06]\], weak reference objects: "... do not prevent their referents from being made finalizable, finalized, and then reclaimed."

A referent is the object that is being referred to. As soon as any strong references to the object are found to have phased out, the garbage collector reclaims the referent. With {{WeakHashMap}}, the map's _key_ is weakly A referent is the object that is being referred to. and

Keys asheld a result determines whether the corresponding referentsin {{WeakHashMap}} objects are readyreferenced tothrough beweak collectedreferences. AnObjects objectbecome becomes eligible for garbage collection when they onlylack weakstrong references. toConsequently, theuse referentof exist. A weak referencereferences allows the code to refer to the referent without holding itsdelaying garbage collection of the referent. This approach is suitable only suitable when the lifetime of the object is required to be the same as the lifetime of the key. 

ItSimply is not enough to facilitate the facilitating garbage collection of unneeded objects through withuse of weak references is insufficient. ItPrograms ismust criticalalso to prune the data structure so that additional morelive entries can be accommodated in the newly created space. ThisOne canpruning betechnique achievedis byto callingcall the {{get()}} method of {{WeakHashMap}} and removing theany entry that corresponds to thea {{null}} return value (polling). AUse moreof efficientreference methodqueues is toa usemore aefficient referencemethod queue \[[Goetz 2005b|AA. Bibliography#Goetz 05b]\].

h2. Compliant Solution (Reference Queue)

Reference queues provide a way to receive notifications when a referent is garbage collected. IfWhen the referent is assigned the value {{null}}, it is eventually garbage collected. However, the {{HashMap}} continues to strongly reference both the {{WeakReference}} object and the corresponding value (for each entry in the {{HashMap}}). 

As soonWhen as the GC clears the reference (whichthat referred to the referent), it adds the corresponding {{WeakReference}} object to the reference queue. It The {{WeakReference}} object remains there unlessin 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 hashmap is also garbage collected. Alternatively, this two-step procedure can be carried out manually by using the following code:

{code: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);

    while ((wr = (WeakReference) queue.poll()) != null) { // poll for dead entries before adding more
      m.remove(wr); // Removes the WeakReference object and the value (not the referent)
    }  
    m.put(wr, ip);
  }

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

Note that the two-argument constructor of {{WeakReference}} takes a {{Queue}} argument and must be used to perform direct queue processing. Dead entries mayshould be pruned prior to insertion.

h2. Compliant Solution (Soft References)

ItUse of soft references is also permissible to use softpermitted. Soft references because they guarantee that the referent will be reclaimed before an {{OutOfMemoryError}} results, and also butthat nothe soonerreferent thanwill theremain timelive whenuntil memory begins to run out.

{code: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) {
      m.remove(sr); // Removes the WeakReference object and the value (not the referent)
    }  
    m.put(sr, ip);
  }

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

Soft references are preferred over weak references for applications such as caching because weak references are garbage collected more aggressively, to the point that they become unsuitable.

h2. Risk Assessment

Memory leaks in Java applications may be exploited to cause denial of service.

|| Guideline || Severity || Likelihood || Remediation Cost || Priority || Level ||
| MSC06-J | low | unlikely | high | {color:green}{*}P1{*}{color} | {color:green}{*}L3{*}{color} |



h3. Automated Detection

TODO



h3. Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this guideline on the [CERT website|https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+MSC01-J].

h2. Bibliography

\[[API 2006|AA. Bibliography#API 06]\] Class Vector, Class WeakReference
\[[Gupta 2005|AA. Bibliography#Gupts 05]\]
\[[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 6: Eliminate obsolete object references
\[[Commes 2007|AA. Bibliography#Commes 07]\] Memory Leak Avoidance
\[[Goetz 2005|AA. Bibliography#Goetz 05]\] Lapsed listeners
\[[Goetz 2005b|AA. Bibliography#Goetz 05b]\] "Memory leaks with global Maps" and "Reference queues" 
\[[Gupta 2005|AA. Bibliography#Gupts 05]\]
\[[MITRE 2009|AA. Bibliography#MITRE 09]\] [CWE ID 401|http://cwe.mitre.org/data/definitions/401.html] "Failure to Release Memory Before Removing Last Reference (aka 'Memory Leak')"

----
[!The CERT Oracle Secure Coding Standard for Java^button_arrow_left.png!|MSC05-J. Store passwords using a hash function]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[!The CERT Oracle Secure Coding Standard for Java^button_arrow_up.png!|49. Miscellaneous (MSC)]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[!The CERT Oracle Secure Coding Standard for Java^button_arrow_right.png!|MSC07-J. Minimize the scope of the SuppressWarnings annotation]