■失敗例
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 elm) { ensureCapacity(); elements[size + 1] = elm; } public Object pop() { if(size == 0) { throw new EmptyStackException(); } return elements[--size]; } private void ensureCapacity() { if(elements.length == size) { elements = Arrays.copyOf(elements, 2 * size + 1) } } }
■修正
以下のようにしてオブジェクトの参照にnullをセットして参照を取り除く。
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 elm) { ensureCapacity(); elements[size + 1] = elm; } public Object pop() { if(size == 0) { throw new EmptyStackException(); } Object elm = elements[--size]; elements[size] = null;// 廃れた参照を取り除く return elm; } private void ensureCapacity() { if(elements.length == size) { elements = Arrays.copyOf(elements, 2 * size + 1) } } }
一般的に独自のメモリ管理をするコードは意図しないオブジェクト保持を起こしやすい。また、キャッシュにおいてもオブジェクトが参照を残したままにする事によってメモリリークを起こすためWeakHashMapなどを用いるべきである。
■まとめ
- 使い終えたオブジェクトにnullを代入するのは例外的ある
- 廃れた参照を排除する最善の方法は、参照が含まれていた変数をスコープの外に出す事である(スタック云々)