다 쓴 객체의 참조를 해제하라(Effective Java).

Choizz·2023년 7월 24일
0

이펙티브 자바

목록 보기
7/13

오늘은 이펙티브 자바 중 "다 쓴 객체의 참조를 해제하라"에 대한 내용을 포스팅하겠습니다.

먼저, 객체의 참조에 대해서 말씀드리겠습니다.

Foo foo = new Foo();

위 코드에서 foo는 Foo 객체의 참조 변수입니다. 즉, foo라는 참조 변수에 Foo 객체의 주소값이 들어가 있는 것 입니다.

쉽게 말해서, 참조라는 것은 어떤 객체나 배열 등의 주소값을 가지고 있는 것이라고 생각하면 될 것 같습니다.

Java에서는 객체 생성되고 사라질 때, 가비지 컬렉션이 사용됩니다. 가비지 컬렉터가 참조되지 않고 있는 객체들을 찾아서 제거해주는 것입니다.

하지만, 모든 객체가 다 가비지 컬렉터에 의해서 제거되는 것이 아닙니다.


객체의 참조가 해제되지 않는 경우

  • 객체의 참조가 제거되지 않는 경우가 있습니다. 책에서 나온 경우로는 스택, 캐시, 리스너, 콜백 등이 있습니다.
  • 그리고 캐시나 스택들은 자료구조로 배열, 리스트, 맵 등을 사용합니다. 배열이나 리스트들을 사용해 저장되는 객체들은 가비지 컬렉터에 의해 제거되지 않습니다. 그 객체가 실제로 사용되는지와 상관없이 말입니다.
  • 즉, 메모리 누수가 일어나는 것입니다.

해결 방법

1. null로 참조를 해제한다.

  • 예를 들어, Stack에서 pop을 할 때 null을 사용해서 참조를 해제할 수 있습니다.
//..위에 다른 코드
      public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] = null; // 다 쓴 객체 참조 해제
        return result;
    }
// 밑에 다른 코드    

2. Weak Reference를 사용한다.

  • weak reference로 자료구조를 사용한다면 객체가 더 이상 참조되는 경우가 없는 경우 가비지 컬렉션 때, 참조를 없앨 수 있는 것을 말합니다.
  • WeakHashMap 등의 자료구조를 사용할 수 있습니다.

3. 직접 제일 오래된 객체 참조를 찾아서 삭제한다.

  • LRU 캐시를 사용하여 오래된 객체 참조를 삭제하는 방법이 있습니다.
  • 이때, 백그라운드 스레드를 이용해서 LRU 알고리즘을 이용한다면 일정 주기로
    사용하지 않은 객체를 제거할 수 있습니다(Scheduled Executer Service 이용).
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
PostRepository postRepository = new PostRepository();
CacheKey key1 = new CacheKey(1);

postRepository.getPostById(key1);

Runnable removeOldCache = () -> {
Map<CacheKey, Post> cache = postRepository.getCache();
Set<CacheKey> cacheKeys = cache.keySet();
Optional<CacheKey> key = cacheKeys.stream().min(Comparator
											.comparing(CacheKey::getCreated));
key.ifPresent((k) -> {
               cache.remove(k);
            		}
             );

정리

  • 객체의 참조를 가지고 있는 자료구조를 사용할 경우에는 사용하지 않는 객체가 존재할 수 있기 때문에 메모리 누수가 발생할 수 있습니다.
  • 의외에도 메모리가 누수되는 경우는 여럿있을 것입니다.
  • 개발자는 메모리 누수를 주의해서 개발을 해야할 것 같습니다.

reference

profile
집중

1개의 댓글

comment-user-thumbnail
2023년 7월 24일

좋은 글 감사합니다. 자주 올게요 :)

답글 달기