JAVA/Effective Java

아이템7. 다 쓴 객체 참조를 해제하라.

hyun-1200 2022. 5. 21. 23:40

아이템7. 다 쓴 객체 참조를 해제하라

  • 자바의 가비지 컬렉터를 통해 메모리 관리에 신경쓰지 않아도 된다고 오해할 수 있지만, 절대 아니다.
  • 가비지 컬렉션 언어에서는 메모리 누수를 찾기가 아주 까다롭다.
  • 객체 참조 하나를 살려두면 가비지 컬렉터는 그 객체뿐 아니라 그 객체가 참조하는 모든객체(그리고 또 그 객체들이 참조하는 모든객체..)를 회수해가지 못한다.
  • 해법은 해당 참조를 다 썼을때 null 처리(참조해제)하면 된다.
  • null를 하면 null처리한 참조를 실수로 사용하려하면 NullPointerException을 던져 오류를 알 수 있다.
  • 참조해제하는 가장 좋은 방법은 그 참조를 담은 변수를 유효범위(scope) 밖으로 밀어내는 것이다.
  • 모든 객체를 다 쓰지마자 null처리로 모두 바꾸는 일은 프로그램을 필요이상으로 지저분하게 만들 뿐이다.
  • 객체 참조를 null 처리하는 일은 예외적인 경우여야 한다.

자기 메모리를 직접 관리하는 클래스라면 프로그래머는 항시 메모리 누수에 주의해야 한다.

1. Stack 클래스

  • 자기 메모리를 직접 관리하는 Stack은 메모리 누수가 발생한다.
  • 비활성 영역이 되는 순간 null 처리해서 해당 객체를 더는 쓰지 않을 것임을 가비지 컬렉터에 알려야 한다.

2. 캐시

  • 캐시는 메모리 누수를 일으키는 주범이다.
  • 캐시 외부에서 키를 참조하는 동안만 엔트리가 살아 있는 캐시가 필요한 상황이라면 WeakHashMap을 사용해 캐시를 만들자.

3. 리스너 혹은 콜백

  • 클라이언트가 콜백만 등록하고 명확한 해지를 하지 않는다면, 뭔가 조치해주지 않는 한 콜백을 계속 쌓여갈 것이다.
  • 이럴 때 콜백을 약한참조로 저장하면 가비지 컬렉터가 즉시 수거해 간다.

정리

메모리 누수는 겉으로는 잘 드러나지 않아 시스템에 수년간 잠복하는 사례도 있다. 
이런 누수는 철저한 코드 리뷰나 힙 프로파일러 같은 디버깅 도구를 동원해야만 발견되기도 한다.
그래서 이런 종류의 문제는 예방법을 익혀두는 것이 매우 중요하다.