Versions Compared

Key

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

Even though Java supports memory management through garbage collection, there are innumerable possibilities of introducing memory leaks due to programming errors. Furthermore, the garbage collector collects only the unreachable objects and not those that are still reachable. The presence of reachable objects that remain unused clearly call calls for memory mismanagement.

Depending on program scale and available memory, one of the most undesired least desirable errors, the OutOfMemoryError may manifest itself wherein the heap space runs out causing program failure.

...

This noncompliant example shows a leaking vector Vector object. This The memory leak quickly exhausts the heap space as the programmer has mistakenly written the condition for removing the vector element as n>0 n > 0 instead of n>n >= 0. As a result, in every iteration, the method leaks one vector element.

Code Block
bgColor#FFCCCC
public class Leak {
  static Vector vector = new Vector();
  public void leakingVector(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.leakingVector(1);
      i++;
    }
  }
}

Compliant Solution (1)

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

Code Block
bgColor#ccccff
for (int n=count-1; n>=0; n--) {
  vector.removeElementAt(n);
}	

...

Wiki Markup
An alternative (and preferable) way to clear the {{vector}} is to use the {{vector.clear()}} method. Likewise,  if a range of elements has to be released from athe {{vector}}, {{vector.subList(fromIndex, toIndex).clear()}} can be used. In this case the {{fromIndex}} and the {{toIndex}} wouldcan both be {{0}} as the {{count}} variable is {{1}} on each iteration. \[[API 06|AA. Java References#API 06]\]

...

Noncompliant Code Example

This noncompliant code example creates a HashMap instance field within the class body but uses it only in the doSomething method. Sometimes, it It is not obvious that it will continue continues to persist as long as the class BadScope's instance is alive.

...

Noncompliant Code Example

This noncompliant code snippet is an example of demonstrates unintentional object retention and is commonly called the Lapsed Listener. The button continues to hold a reference of the reader object even after completion of the readSomething() method. As a result, the garbage collector will does not collect the reader object. A similar problem occurs with inner classes as they hold an implicit reference to the outer class.

...

To solve this problem, a matching pair of the removeActionListener should be used, as shown below. Unfortunately, this is not the panacea because an exception in the reader.readSomething() method can change the control flow in such a way that the removeActionListener statement is never executed.

Code Block
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 handleto exceptionhandler */ }		 

Compliant Solution

The solution is to use the finally block to ensure that the reader object's reference is unregistered.

...

Wiki Markup
This example implements a {{stack}} data structure \[[Bloch 08|AA. Java References#Bloch 08]\] Item 6: Eliminate obsolete object references. The main issue is that it does not allow the garbage collector to de-allocate memory after the {{pop}} operation. The object references are retained even after the element is pop'ed. Such _obsolete references_ are not garbage collected automatically. This can get even more deceitful sinceas none of the objects referenced by the offending object get garbage collected either.  

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);
    }
  }
}

...

A common variant of the aforementioned noncompliant code example is the unintentional retention of objects while when using a Map or a similar Collections object. In this example, a server maintains temporary metadata about all secure connections it commits to. Although the metadata is designed to be transient by nature, it persists even after the particular socket is closed. Unless some notification logic is installed, it is impossible to determine the best time to eliminate the object reference. Likewise, nulling out original objects or referents (Socket connections) by itself, proves to be unwieldy.

...

Wiki Markup
This compliant solution uses _weak references_ to ameliorate the issue. Strong references typically used in code, do not allow the garbage collector to reclaim the objects that are stored compositely, such as in a {{Map}}. According to the Java API \[[API 06|AA. Java References#API 06]\], weak reference objects:

...

If the referent is assigned the value null, it will is eventually be garbage collected. However, the hashmap will continue HashMap continues to strongly reference the WeakReference object and the corresponding value (for each entry in the hashmap HashMap). As soon as the GC clears the reference (which referred to the referent), it adds the corresponding WeakReference object to the reference queue. It remains there unless 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 collected. Alternatively, this two-step procedure can be carried out manually by using the following code:

...

Note that the two-argument constructor of WeakReference takes a Queue argument and has to must be used to perform direct queue processing.

It is also permissible to use soft references since because they guarantee that the referent will be reclaimed before an OutOfMemoryError results but no sooner than the time when memory begins to run out.

...

Memory leaks in Java applications may be exploited , resulting in to cause denial - of - service attacks.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC01- J

low

unlikely

high

P1

L3

...