Java

Garbage Collector

iksadnorth 2023. 7. 17. 13:49

👣 개념

가비지 컬렉터는 JVM에 구성요소로서 RunTime Data Area 내부의
Heap 영역에 할당된 메모리 영역을 해제하기 위해 존재하는 장치다.

Stack 영역과 달리 Heap 영역의 메모리는 의도적인 메모리 해제 과정을 거치지 않으면
결국 사용하지 않음에도 불구하고 사용할 수 없는 메모리 공간으로 가득찬다.
이를 메모리 누수라고 한다.

 

이런 상황을 피하기 위해 C 언어에서는 개발자가 직접 해제하는 방식을 택하고 있는데
이는 비즈니스 코드 이외의 코드도 작성해야 하기에 이를 불필요한 Cost가 많이 소모된다.
자바의 경우 JVM의 Garbage Collector가 이런 과정을 자동화하게 된다.

👣 Stop The World

GC는 사용자가 직접 상황 판단을 하는 것이 아니다 보니 성능에 문제를 일으키는 경우가 존재한다.

Stop-The-World란?
GC를 작동시키기 위해 GC Thread를 제외한 모든 Thread의 작동을 일시정지 시키는 상황을 일컫는 말.

이렇게 Stop-The-World가 발생하면 기존에 작동하는 서버가 중지되어
요청을 처리하지 않는 성능 상의 문제를 일으킬 수도 있어서 주의해야 한다.

👣 메모리 제거 대상

정확히 말하면 Heap의 모든 메모리가 제거 대상인 것은 아니다. 
RunTime Data Area[Stack, Method Area, ...] 중 해당 메모리가
더 이상 참조하지 않는 Heap 메모리를 제거하는 것이다.

 

👣 Mark & Sweep & Compaction

참조 여부를 따지는지 방식을 Mark라고 한다.
우선 Root Space[각종 RunTime Data Area에 속한 것들. 단, Heap 제외]에서
시작하는 그래프를 순회하면서 참조되는 메모리들을 찾아 간다.
그러면서 각 메모리에 Reachable 여부를 Marking한다.

실제로 Unreachable한 메모리를 해제하는 과정을 Sweep라고 한다.

메모리 사이사이의 공간은 불필요한 단편화를 일으키므로
좀더 효율적인 메모리 할당을 위해 빈 공간을 차곡차곡 채운다.
이 과정을 Compaction라고 한다.

👣 GC 작동 조건

위 방법을 보면 알겠지만 많은 연산량을 요구하는 것을 알 수 있다.
때문에 이런 연산을 수행하는 시기는 딱 필요한 시기에 적용하는 것이 합리적으로 보인다.
그렇다면 어떤 조건이 충족되어야 GC가 작동하는지 알아야 한다.

우선 이를 알기 전에 'Weak Generational Hypothesis' 이론을 이해해야 한다.

Weak Generational Hypothesis 이론이란?

1. 대부분의 객체는 금방 접근 불가능한 상태(Unreachalbe)가 된다.
2. 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.

즉, 대부분의 객체는 초기에 빠르게 사라지고 오래된 객체는 쉽게 사라지지 않는다는 특성을 이야기 하는 이론이다.
때문에 일련의 필터를 거친 객체들은 쉽게 사라지지 않을 객체들이기에
그들을 따로 모아 그들끼리 관리를 해도 무방하다.

  1. Young Generation
    이 곳이 초기에 빠르게 사라질 객체들이 머무르는 공간이다. Eden과 Survivor 1, 2 영역이 이곳에 포함된다.
    이 곳에서의 GC 과정을 Minor GC 라고 한다.
  2. Old Generation
    이 곳이 쉽게 사라지지 않을 객체들이 머무르는 공간이다. Old와 Permanent 영역이 이곳에 포함된다.
    이 곳에서의 GC 과정을 Major GC 라고 한다.

👣 Minor GC 작동 과정

  1. 우선 객체를 Heap 영역에 저장하면 Eden 영역에 차곡차곡 쌓이게 된다.
  2. 그러다 Eden 영역에 꽉 차게 되면 Minor GC가 작동하며 Mark & Sweep을 하게 된다.
  3. 만약 Minor GC 후에 살아남는 객체가 존재한다면 Survivor 1영역으로 넘기게 된다.
  4. 이후 Eden 영역이 또 가득차게 되면 Mark & Sweep을 하게 되고 다음 Survivor 2로 넘기게 되는데 이 때, Survivor 2에는 Eden에 있던 객체 뿐만 아니라 Survivor 1 영역에 있던 객체도 함께 넘긴다. 이 때, Survivor 1에 있던 객체들은 age값을 +1한다.
  5. Eden 영역이 가득 찰 때마다 위 과정을 계속 반복한다.

👣 Major GC 작동 과정

  1. Survivor 영역에 객체의 age가 일정 값을 넘기게 되면 Old Generation으로 넘기게 된다.
  2. 그러다 Old영역에 꽉 차게 되면 Major GC가 작동하며 Mark & Sweep을 하게 된다.

보통 Eden 영역은 협소하기 때문에 자주 발생하면서 매우 짧은 작동 시간을 가진다.
하지만 Old Generation의 크기는 크기 때문에
성능 상 영향을 주는 GC 과정은 Major GC 과정이다.
  Minor GC Major GC
대상 Young Generation Old Generation
실행 시점 Eden 영역이 꽉 찬 경우 Old 영역이 꽉 찬 경우
실행 속도 빠르다 느리다

 

'Java' 카테고리의 다른 글

Auto Boxing & Auto UnBoxing  (0) 2023.07.17
문자열  (0) 2023.07.17
Call By Value & Call By Reference  (0) 2023.07.17
JDK, JRE, JVM  (0) 2023.07.17
Java 코드 작성부터 실행까지  (0) 2023.07.17