Sunday, September 28, 2014

Memory Leak

As we know Java is the garbage collected language. Programmer do not need to worry about the memory management. But its not true always.

The memory leak can reduced the performance due to the increased garbage collector activity resulting disk paging and even program failure with an OutOfMemoryError.

Consider the following simple implementation of stack,

import java.util.Arrays;
import java.util.EmptyStackException;

/**
 *
 * @author
 */
public class Stack {

    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack() {
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop() {
        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) {
            elements = Arrays.copyOf(elements, 2 * size + 1);
        }
    }
}

Did you spot the memory leak ?

If the stack grows and then shrinks, the objects that were popped off the stack will not be garbage collected, This is because the stack maintain the absolute reference to these objects.

If an object reference is unintentionally retained, not only object excluded from garbage collection, but also many many objects may be prevented from being garbage collected, with potentially large effect on performance.

Solution : null out the reference once they become obsolete.

public Object popCorrected() {
        if (size == 0) {
            throw new EmptyStackException();
        }
        Object result = elements[--size];
        elements[size] = null; // Eliminate obsolete reference
        return result;
    }


whenever a class manages its own memory, the programmer should be alert for memory leaks.

Another common source of memory leaks is caches.

Source: Effective Java 2nd Edition, Chapter 2