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
에 콜백을 키로 저장하면 해결할 수 있다.