Java ‐ 다 쓴 객체 참조를 해제하라[Effective Java Item 7] - dnwls16071/Backend_Summary GitHub Wiki
다 쓴 객체 참조를 해제하라.
// Bad
public class Stack {
private static final int DEFAULT_INITAL_CAPACITY = 16;
private Obejct[] elements;
private int size = 0;
public Stack() {
elements = new Object[DEFAULT_INITAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++];
}
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);
}
}
pop() 메서드를 호출하면 실제 값은 삭제되지 않고 인덱스만 한칸씩 이동하는 것으로 메모리 누수가 발생하게 된다.
// Good
public Object pop() {
if (size == 0) {
return new EmptyStackException();
}
Object result = elements[--size];
elements[size] = null; // 다 쓴 객체의 참조를 null로 해제한다.
return result;
}
- 다 쓴 참조를 null 처리하면 다른 이점도 따라온다.
- 만약 null 처리한 참조를 실수로 사용하게 되면 프로그램은 즉시 NPE를 던지며 종료된다.
- 지역 변수로 선언된 컬렉션 타입은 메서드가 끝나면(=스코프에서 벗어나면) 더 이상 참조가 없기에 GC의 대상이 된다. 따라서 일반적으로 메서드가 종료되면 메모리가 해제된다.
- 반대로 그 컬렉션 타입이 static으로 선언되어 참조가 유지되면 GC가 회수되지 못해 메모리가 유지되어 잠재적 메모리 누수가 발생하게 된다.