연구실에서 java세미나를 하던 도중 멘토가 쓰레기수집기(Garbage Collector)에 관해 제대로 알고 있는지 확인을 위해 질문을 하셨고, 얼추 대답은 했지만 좀 더 깊게 알 필요가 있다고 하셔서 자료를 찾아 공부를 해보았다.

우선 java에서는 '참조하지 않는 객체' 혹은 '유효하지 않은 메모리'를 쓰레기(=Garbage)로 분류하고, C++와 다르게 개발자가 프로그램 코드로 메모리를 명시적으로 해제하지 않기 때문에 Garbage Collector가 garbage를 찾아 지우는 작업을 한다. 다만 모든 메모리 누수를 잡아주는 것은 아님으로 메모리 누수에 대한 경계를 늦추어서는 안된다.

String[] array = new String[2];
array[0] = '1';
array[1] = '2';
array = new String[] {'G', 'C'};

위와 같이 먼저 삽입되어있던 '1'과 '2'는 새롭게 추가된 'G', 'C'로 인해 주소가 유효하지 않으므로 Garbage로 부른다.

💡 Garbage Collector가 수행하는 작업 2가지

  1. 힙(heap)영역 내에 가비지(garbage)를 찾아낸다.
  2. 찾아낸 가비지를 회수하여 힙의 메모리를 회수한다.

💡 stop-the-world

GC를 실행시키기 위해 JVM이 애플리케이션 실행을 멈추는 것으로, stop-the-world가 실행되면 GC를 실행하는 스레드를 제외한 나머지 스레드는 모두 작업을 멈춘다. GC 작업을 완료한 이후에야 중단했던 작업을 다시 시작한다. 어떤 GC 알고리즘을 사용하더라도 stop-the-world는 발생하고, 대개 GC 튜닝이란 이 stop-the-world 시간을 줄이는 것이다.

💡 Mark and Sweep

GC가 스택의 모든 변수 또는 Reachable 객체를 스캔하면서 각각 어떤 객체를 참조하는지 찾는 과정Mark이고, 이 과정에서 stop-the-world가 발생한다. 이후 Mark 되어있지 않는 객체들을 힙에서 제거하는 과정Sweep이다.

💡 Young 영역과 Old 영역

JVM을 크게 물리적 공간으로 나누면 Young 영역과 Old 영역이 있다. (Perm 영역은 잠시 배제하였다)

  • Young 영역에서는 주로 새롭게 생성한 객체의 대부분이 이곳에 위치한다. 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 매우 많은 객체가 이 곳에 생성되었다가 사라진다. 이 영역에서 Minor GC가 발생한다.

  • Old 영역에서는 접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 이 곳으로 복사된다. 대부분 Young 영역보다 크게 할당하며, Young 영역보다 GC는 적게 발생한다. 이 영역에서 Major GC가 발생한다.

  • Young 영역은 Eden 영역과 2개의 Survive 영역으로 구성되며 Eden 영역에 최초로 객체가 만들어지고, Survivor 영역을 통해서 Old 영역으로 오래 살아남은 객체가 이동한다는 사실은 꼭 기억하기 바란다.

    Old 영역의 구성에 대한 내용은 D2의 글을 참조하였다.

  • Reachability
    java의 GC는 객체가 garbage인지 판별하기 위해 reachability라는 개념을 사용한다. 어떤 객체에 유효한 참조가 있으면 'reachable'로, 없으면 'unreachable'로 구별하고, 'unreachable' 객체를 garbage로 간주한다.

    이 부분에 대해 더 알아보려면 이 글을 참고하자.

profile
백엔드 개발자로 등 따숩고 배 부르게 되는 그 날까지

0개의 댓글