public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAILT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAILT_INITIAL_CAPACITY];
}
public void push(Object e) {
encureCapacity(); // 배열 크기를 늘려야할 때 늘려주는 메서드
elements[size++] = e;
}
public Object pop() {
if (size == 0) {
throw new EmptyStackException();
}
return elements[--size]; // 참조가 여전히 남아있음
}
}
OutOfMemoryError를 일으킨다.pop() 메서드에서 꺼내진 객체들을 더 이상 사용하지 않아도 참조를 여전히 가지고 있기에 GC가 회수하지 않는다.이를 해결하기 위해선 참조를 다 썼을 때 null 처리하면 된다.
public Object pop() {
if (size == 0) {
throw new EmptyStackException();
}
Object result = elements[--size];
elements[size] = null;
return result;
}
null 처리하게 되면 실수로 이 참조를 사용하려 하면 NPE가 발생하기에 프로그램 오류를 조기에 발견할 수도 있다.null 처리하게 되면 코드가 지저분해지기 때문에 null 처리는 예외적인 경우여야 한다.Stack 코드에서 null 처리가 필요했던 이유는 스택이 ‘자기 메모리를 직접 관리’하기 때문이다.
Stack에서 elements 배열로 원소들을 관리하고 size 이하의 활성화 영역과 size 밖의 비활성화 영역이 존재한다.WeakHashMap을 사용해 캐시를 만들면 된다.WeakHashMap을 사용하면 다 쓴 엔트리는 그 즉시 자동으로 제거된다.WeakHashMap에 콜백을 키로 저장하면 해결할 수 있다.