[Java] [Read Effective Java] Chapter 2, Item 6 Remove obsolete object references

1 minute read

Get rid of obsolete object references

From the perspective of languages that do manual memory management, such as C, the garbage collector may seem magical. However, there are still causes for memory leaks, so be careful.

Sample code

Example 1


// Can you find a "memory leak"?
public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack() {
        this.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];
    }

    /**
     * Every time you need to make the array larger, roughly double the points,
     * Secure at least another element.
     */
    private void ensureCapacity() {
        if (elements.length == size)
            elements = Array.copyOf(elements, 2 * size + 1);
    }
}

Example 2


public Object pop() {
    if (size==0)
        throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null; // remove obsolete references
    return result;
}

Three causes of memory leak

First reference is obsolete

Example 1 looks fine, but it holds the obsolete reference. You can prevent memory leak by setting null to the reference you no longer need as in Example 2.

However, you don’t have to set it too null for every program you’ve used. The Stack class has its own memory management. The garbage collector can’t know which references to such classes are not needed. By manually setting null you can effectively tell the garbage collector what’s invalid.

Second cache

Once you have an object reference in the cache, it’s easy to forget that it’s there, and it’s easy to leave it in the cache long after the object reference has no meaning. As long as there is a reference to the key of the entry that is outside the cache, if you implement a meaningful cache for that entry, then you should represent that cache with a WeakHashMap. WeakHashMap: Automatically removed when entries are obsolete

Third listener and callback

If you implement an API that does not explicitly cancel registration, callbacks will be accumulated unless you do something. The best way to ensure that callbacks are garbage collected quickly is to store only weak references to them.

Continue

[Read Effective Java] Chapter 2, Item 7 “Avoid finalizers” https://qiita.com/Natsukii/items/785ae41361cb7324e45b