이펙티브 자바:: 아이템 7 <다 쓴 객체 참조를 해제하라>
🙉

이펙티브 자바:: 아이템 7 <다 쓴 객체 참조를 해제하라>

Created
Aug 11, 2024 06:51 AM
Last edited time
Last updated August 22, 2024
Tags
Language
Language
Java
URL

Intro::

이펙티브 자바 정리본입니다.
 
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]; } // 제대로 구현한 pop 메서드 // 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); } }
 
위의 코드처럼 pop 메서드를 구현할 경우 메모리 참조가 해제되지 않기 때문에 gc가 메모리를 해제해 주지 않는다. 이 경우 OutOfMemoryError가 발생해 프로그램이 예기치 않게 종료될 수 있다.
해결방법은 간단하게 다 쓴 객체를 null 로 처리해 참조해제 해주면 된다. 하지만 모든 객체를 다 쓰자마자 일일이 null 처리하는 것은 바람직 하지 않다. 프로그램을 필요이상으로 지저분하게 만들게 된다. 객체 참조를 null 처리하는 일은 예외적인 경우여야 한다. 다 쓴 참조를 해제하는 가장 좋은 방법은 그 참조를 담은 변수를 유효 범위(scope) 밖으로 밀어내는 것이다.
일반적으로 자기 메모리를 직접 관리하는 클래스라면 프로그래머는 항시 메모리 누수에 주의해야 한다. 원소를 다 사용한 즉시 그 원소가 참조한 객체를 더 쓰지 않을 것임을 gc에 알려야한다.

메모리 누수의 주범

  1. 자기 메모리를 직접 관리하는 클래스
  1. 캐시
    1. WeakHashMap을 사용해 캐시를 만든다면 다 쓴 엔트리는 자동으로 제거되어집니다.
  1. 리스너(listener) 혹은 콜백(callback)
    1. 약한 참조로 저장하면 가비지 컬렉터가 즉시 수거해간다.
 
 

질문

객체를 갈아끼운다면 gc가 참조메모리 해제를 해주는가??
element[1] = Something(a); element[1] = Something(b); //Something(a)에 대한 객체 참조가 해제되나??
그렇다. 다른 곳에서 참조하고 있지 않는 이상 gc가 자동으로 메모리를 해제해준다.
 
WeakHashMap을 사용하라는데 그게 뭘까..??
WeakHashMap은 키에 약한 참조를 사용하는 Map의 한 종류입니다. WeakHashMap의 키 객체는 약한 참조로 관리되기 때문에, 키에 대한 강한 참조가 다른 곳에서 사라지면, 가비지 컬렉터가 해당 키와 관련된 엔트리를 제거할 수 있습니다.

References::

이펙티브 자바 / 조슈아 블로크 지음 (프로그래밍 인사이트)

Loading Comments...