윤개발

[ITEM7] 다쓴 객체 참조를 해제하라. 본문

책 내용 요약/Effective Java 3판

[ITEM7] 다쓴 객체 참조를 해제하라.

DEV_SJ 2020. 4. 14. 13:28

가비지 컬렉션 언어에서는 메모리 누수를 찾기가 아주 까다롭다.
때문에 해당 참조를 다 사용한 후 null 처리하면 된다.

Stack에서 메모리를 직접 관리하는 예제

public class Stack { 
    private Object[] elements; 
    ... 
    public Object pop() { 
        if (size == 0) 
            throw new EmptyStackException(); 
        return elements[--size]; // 문제점 
    } 
    ... 
}

위 코드는 pop() 메소드에서 size를 감소시키지만 해당 값은 그대로 있어 메모리 누수가 발생하는 것을 볼 수 있다.

스택에서 pop을 할 경우 null 처리를 해준 코드

Object result = elements[--size]; 
elements[size] = null; 
return result;

이러한 방법의 이점은 null 처리한 객체를 다시 참조할때 NullpointerException을 던지며 잘못된 참조를 방지한다.
자기 메모리를 직접 관리하는 클래스라면 프로그래머는 항시 메모리 누수에 주의해야 한다.

또한 캐시역시 메모리 누수를 발생시키는 주범이다.
캐시를 직접 구현할 경우 객체를 캐시에 넣어두고 잊는 등 문제의 소지가 있다.
이를 방지하고자 WeakHashMap을 사용하여 캐시를 만든다면 다 쓴 엔트리는 즉시 제거될 것이다.

메모리 누수의 세 번째 주범은 리스너 혹은 콜백이다.
클라이언트가 콜백을 등록만 하고 해지하지 않는다면 계속해서 콜백이 쌓여간다.
이럴 때 weak reference로 저장하면 가비지 컬렉터가 즉시 수거해간다.


정리

메모리 누수는 겉으로 잘 드러나지 않아 수년간 잠복하는 사례도 있다.
코드리뷰나 힙 프로파일러 같은 디버깅 도구를 동원해야 하므로 예방법을 익혀두는 것이 중요하다.

Comments