[아이템 7] 다 쓴 객체 참조를 해제하라
- 가비지 컬렉션 언어에서는 의조치 않게 객체를 살려두는 메모리 누수를 찾기가 아주 까다로움
- 객체 참조 하나를 살려두면 가비지 컬렉터는 그 객체뿐 아니라 그 객체가 참조하는 모든 객체를 회수해가지 못함
- 단 몇 개의 객체가 매우 많은 객체를 회수되지 못하게 할 수 있고 잠재적으로 성능에 악영향을 줄 수 있음
메모리 누수의 첫 번째
- 일반적으로 자기 메모리를 직접 관리하는 클래스라면 항시 메모리 누수에 주의해야함
- 객체 참조를 null 처리하는 일은 예외적인 경우여야 함(모든 객체에 적용할 필요 X)
- 다 쓴 참조를 해제하는 가장 좋은 방법은 그 참조를 담은 변수를 유효 범위(scope) 밖으로 밀어내는 것
예시 코드
public class Stack {
private Object[] elements;
private int size = 0;
// ...생략...
// 메모리 누수 문제가 되는 부분
public Object pop() {
if (size == 0) {
throws new EmptyStackException();
}
return elements[--size];
}
// ...생략...
}
// ...생략...
public Object pop() {
if (size == 0) {
throws new EmptyStackException();
}
Object result = elements[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
// ...생략...
메모리 누수의 두 번째
- 캐시 역시 메모리 누수를 일으키는 주범
- 캐시를 만들 때 보통은 캐시 엔트리의 유효 기간을 정확히 정의하기가 어려움
- 시간이 지날수록 엔트리의 가치를 떨어뜨리는 방식을 흔히 사용
메모리 누수의 세 번째
- 리스너 혹은 콜백
- 클라이언트가 콜백을 등록만 하고 명확히 해지하지 않는다면, 조치하지 않는 한 콜백이 계속 쌓여감
- 콜백을 약한 참조로 저장 필요
참고