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 as a result of 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 calls for indicates memory mismanagement.

Depending on program scale and available memory, one of the least desirable errors, the OutOfMemoryError may manifest manifests itself wherein when the heap space runs out causing . This usually results in program failure.

Noncompliant Code Example

This noncompliant example shows a leaking Vector object. The memory leak quickly exhausts the heap space as the programmer has mistakenly written 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.

...

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

Compliant Solution (2)

To be safe, it is usually better It is preferable to use the standard language semantics where possible, as shown belowin this compliant solution.

Code Block
bgColor#ccccff
while (!vector.isEmpty()){
  vector.removeElementAt(vector.size() - 1);	        	    
}

...

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 the {{vector}}, {{vector.subList(fromIndex, toIndex).clear()}} can be used. In this case the {{fromIndex}} and the {{toIndex}} can both be {{0}} as the {{count}} variable is {{1}} on each iteration. \[[API 06|AA. Java References#API 06]\]

...

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

...

Code Block
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
  }
}

Noncompliant Code Example

To solve resolve 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 to handler */ }		 

Compliant Solution

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

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

Noncompliant Code Example

Wiki Markup
This example implements a {{stack}} data structure \[[Bloch 08|AA. Java References#Bloch 08]\]. 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 asbecause none of the objects referenced by the offending object get garbage collected.  

...

This compliant solution assigns null values to all obsolete references. The garbage collector can now include this object in its list of objects to free. A NullPointerException exception results on subsequent attempts to access the particular object.

...

Wiki Markup
While these examples may not model production scenarios, it is not uncommon to have _obsolete references_ when dealing with data structures such as hash tables that contain 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 giveshas no specific advantageadvantages. The garbage collector is sufficiently equipped to handle these cases. \[[Commes 07|AA. Java References#Commes 07]\]

Noncompliant Code Example

A common variant of the aforementioned noncompliant code example is the unintentional retention of objects 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
It is not enough to facilitate the collection of unneeded objects with weak references. It is critical to prune the data structure so that more entries can be accommodated in the newly created space. This can be achieved by calling the {{get()}} method of {{WeakHashMap}} and removing the entry that corresponds to the {{null}} return value (polling). A more efficient method is to use a reference queue. \[[Goetz 05b|AA. Java References#Goetz 05b]\]

Compliant Solution

If the referent is assigned the value null, it is eventually garbage collected. However, the HashMap continues to strongly reference the WeakReference object and the corresponding value (for each entry in the 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 must be used to perform direct queue processing.

Compliant Solution

It is also permissible to use soft references 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.

...