Versions Compared

Key

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

...

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

...

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

Compliant Solution (2)

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

...

Wiki Markup
An alternative way toof clearclearing 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 the context of this casecompliant solution, 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 will continue 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) { 
      //* handleHandle exception 
   */ }		 
  }
}

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

Noncompliant Code Example

...

Code Block
bgColor#FFCCCC
Reader reader = new Reader();
button.addActionListener(reader);
try {
  reader.readSomething();  // canCan skip next line
  button.removeActionListener(reader);  // dereferencedDereferenced, but control flow can change
} catch (IOException e) { 
  //* forwardForward to handler */ 
}		 

Compliant Solution

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) { 
  //* handleHandle exception */
} }
finally {
  button.removeActionListener(reader);  // alwaysAlways gets executed
}

Noncompliant Code Example

Wiki Markup
This noncompliant code 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-allocatedeallocate 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 because none of the objects referenced by the offending object get garbage collected.  

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 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 values to all obsolete references. The garbage collector can now include this object individual element-objects in its list of objects to free. A NullPointerException results on subsequent attempts to access the particular object.

...

Wiki Markup
While these examples may not model production scenarios, it is not uncommon to haveuncover _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 has no specific advantages. The garbage collector is sufficiently equipped to handle these cases. \[[Commes 07|AA. Java References#Commes 07]\]

...

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 noncompliant code 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.

Code Block
bgColor#FFCCCC
class HashMemLeak {
  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);  
  }	
}

...

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:

...

 "... 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 referred to and as a result determines whether the corresponding referents are ready to be collected.

...

Code Block
bgColor#ccccff
ReferenceQueue queue = new ReferenceQueue();
WeakReference wr = new WeakReference(key, queue); // twoTwo-arg constructor, key = 'sock'
hashmap.put(wr, value);
while ((wr = (WeakReference) queue.poll()) != null) {
  hashmap.remove(wr); // removesRemoves the WeakReference object and the value (not the referent)
}

...