...
Code Block |
---|
|
import java.util.Vector;
import java.io.IOException;
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 compliant solution corrects the mistake by changing the loop condition to n>=0
.
Code Block |
---|
|
for (int n=count-1; n>=0; n--) {
vector.removeElementAt(n);
}
|
Compliant Solution (2)
To be safe, it is usually better to use the standard language semantics as shown below.
Code Block |
---|
|
while (!vector.isEmpty()){
vector.removeElementAt(n);
vector.size() - 1);
}
|
Noncompliant Code Example
...
Code Block |
---|
|
import java.util.EmptyStackException;
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);
}
}
}
|
Compliant Solution
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.
...