Effect Java 제2판(Joshua Bloch / Addison Wesley) 을 공부하고 정리한 내용 입니다.

6. 쓸모없는 객체 참조를 제거하자.

  1. 어떤 클래스에서 자신의 메모리를 자가기 관리 한다면, 프로그래머는 항상 메모리 누출에 주의 해야 한다.
    따라서 특정 배열 요소가 자유로 사용 가능해질 때는 그 요소에 저장되었떤 객체 참조를 반드시 null 값으로 변경해야 한다.

     
    // 어디에서 "메모리 누출"이 생기는지 찾을 수 있는가?
    public class Stack {
    	private Object[] elements;
    	private int size = 0;
    	private static final int DEFAULT_INITIAL_CAPACITY = 16;
    	
    	public Stack() {
    		elements = new Object[DEFAULT_INITIAL_CAPACITY];
    	}
    	
    	public void push(Object e) {
    		ensureCapacity();
    		elements[size++] = e;
    	}
    	
    	public Object pop() {
    		if (size == 0)
    			throw new EmptyStackException();
    		return elements[--size];
    	}
    	
    	/**
    	 * 배열 요소를 저장하는 필요한 공간을 확인하고
    	 * 배열이 커질 필요가 있을 때는 그 크기를 2배로 늘린다.
    	 */
    	private void ensureCapacity() {
    		if (elements.length == size)
    			elements = Arrays.copyOf(elements, 2 * size + 1);
    	}
    }


    객체들을 가리키는 쓸모 없는 참조를 스택에서 여전히 가지고 있다. 해결책은 쓸모 없는 참조를 null로 만드는 것이다.

     
    public Object pop() {
    	if (size == 0)
    		throw new EmptyStackException();
    	Object result = elements[--size];
    	elements[size] = null; // 쓸모 없는 참조를 제거한다.
    	return result;
    }
    


    이런 문제로 고통을 껵어 본 프로그래머들은 코드 실행이 끝나는 즉시로 너무 지나치게 모든 객체 참조를 null 값으로 바꾸려 한다. 그것은 바람직하지 않다. 프로그램 코드가 필요 이상으로 어수선해지기 때문이다. 객체 참조를 null로 변경하는 것은 꼭 필요할 때만 예외적으로 행해야 한다. 쓸모 없는 참조를 제거하는 가장 좋은 방법은, 참조 값을 갖는 변수가 유효 범위(scope) 밖에 있도록 하는 것이다. 만일 그런 변수가 최소한의 유효 범위 내에 있도록 정의 한다면 자연스레 그렇게 될 것이다.

  2. 메모리 누출이 흔히 생기는 또 다른 근원은 캐시(cache)이다.

    캐시 외부에 캐시의 키(key)에 대한 참조가 있을 동안만 캐시에 저장된 항목이 유효한 그런 캐시를 구현하는 것으로 충분하다면, WeakHashMap을 캐시로 사용하자. 그러면 키로 저장된 객체가 더 이상 참조되지 않을 때 해당 항목이 자동으로 삭제될 것이다. 캐시에 저장된 항목들의 생명주기가 각 항목의 키(값이 아닌)에 대한 외부 참조에 의해 결정되도록 할 때에만 WeakHashMap이 유용하다는 것을 기억하자.

  3. 메모리 누출의 세 번째 근원은 리스너(Listener)와 콜백(callback)이다.
    클라이언트가 콜백을 등록하되 말소는 하지 않는 API를 구현한다면 우리가 뭔가 조치를 취하지 않는 한 콜백은 계속 누적될 것이다.

    콜백이 신속하게 가비지 컬렉션 되도록 하는 가장 좋은 방법은 약한 참조(weak reference)만을 저장 유지하는 것이다. 예를 들어 WeakHashMap의 키로만 콜백을 저장한다.
Posted by outliers
,