Java

[이펙티브자바] 아이템7. 다 쓴 객체 참조를 해제하라.

yerimkoko 2023. 5. 10. 14:11
728x90

이펙티브자바

핵심정리

  • 어떤 객체에 대한 레퍼런스가 남아있다면 해당 객체는 가비지 컬렉션의 대상이 되지 않는다.
  • 자기 메모리를 직접 관리하는 클래스라면 메모리 누수에 주의해야 한다.
    • ex) 스택, 캐시, 리스너 또는 콜백
    • Stack 예시
     public Object pop() {
         if (size == 0)
             throw new EmptyStackException();
    			Object result = elements[--size];
    			elements[size] = null; // 다 쓴 참조 해제
          return result;
     }
    
  • 참조 객체를 null 처리 하는 일은 예외적인 경우이며, 가장 좋은 방법은 유효 범위 밖으로 밀어내는 것이다.
    • but, 예외적인 경우가 흔하다.
public class Stack {

    private Object[] elements;

    private int size = 0;

    private static final intDEFAULT_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();
				Object result = elements[--size];
				elements[size] = null; // 다 쓴 참조 해제

        return result;
    }

/**
     *원소를 위한 공간을 적어도 하나 이상 확보한다.
     *배열 크기를 늘려야 할 때마다 대략 두 배씩 늘린다.
     */

private void ensureCapacity() {
        if (elements.length == size) {
            elements = Arrays.copyOf(elements, 2 * size + 1);
        }
    }

    public static void main(String[] args) {
	        Stack stack = new Stack();

    }
}

메모리를 관리하는 방법

  1. 직접 null 처리
  2. 특정한 자료구조 사용(ex. WeakHashMap)
  3. 직접 빼거나 넣기
public Post getPostById(Integer id) {
   CacheKey key = new CacheKey(id);
   if (cache.containsKey(key)) {
       return cache.get(key);
   } else {
       Post post = new Post();
       cache.put(key, post);
       return post;
   }
}