[Java] Garbage Collector의 동작원리

may_yun·2023년 4월 12일
0

JAVA

목록 보기
5/12

Garbage Collection(GC)의 개념을 안다는 전제하에 GC의 동작 원리부터 설명

Heap영역 Young / Old

Heap영역은 처음 설계될 때 다음의 2가지를 전제 (Weak Generational Hypothesis)로 설계되었다.

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

📌 즉, 객체는 대부분 일회성되며, 메모리에 오랫동안 남아있는 경우는 드물다는 것

효율적인 메모리 관리를 위해, 객체의 생존 기간에 따라 물리적인 Heap 영역을 나누게 되었고 YoungOld 총 2가지 영역으로 설계

Old 영역이 Young 영역보다 크게 할당되는 이유는 Young 영역의 수명이 짧은 객체들은 큰 공간을 필요로 하지 않으며 큰 객체들은 Young 영역이 아니라 바로 Old 영역에 할당되기 때문이다.

1) Young 영역 (Young Generation)

  • 새롭게 생성된 객체가 할당되는 영역
  • 대부분의 객체가 금방 Unreachable 상태가 되기 때문에 많은 객체가 Young 영역에 생성되었다가 사라진다
  • young 영역에 대한 가비지 컬렉션을 Minor GarbageCollection

Young 영역의 3가지 영역

Eden, survivor 0, survivor 1

  • eden
    • new를 통해 생성된 객체
    • 정기적인 쓰레기 수집 후 살아남은 객체들은 Survivor로 보냄
  • Survivor 0 / Survivor 1
    • 최소 1번의 GC 이상 살아남은 객체가 존재
    • 규칙: Survivor 0 또는 Survivor 1 둘 중 하나에는 꼭 비어 있어야 하는 것

2) Old 영역 (Old Generation)

  • young 영역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역
  • young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생
  • old 영역에 대한 가비지 컬렉션을 Major GarbageCollection (Full GC)

Garbage Collector 동작 과정

가비지 컬렉터가 동작하면, 다음과 같은 동작을 수행한다
1. Stop the world
2. Mark and Sweep

Stop the world

JVM이 GC를 실행하기 위해 애플리케이션의 실행을 멈추는 작업
GC를 실행하는 쓰레드 외 다른 모든 쓰레드는 작업이 중단된다
애플리케이션 중단 시간 최소화를 위해서 이 stop the world 작업의 소요시간을 줄이기 위해 다양한 알고리즘을 적용한다

Mark and Sweep

Stop the world 이후 GC가 스택의 모든 변수 또는 접근 가능한 reachable 객체를 스캔

  1. Garbage collector가 Stack의 모든 변수를 스캔하면서 어떤 객체를 참조하고 있는지 찾아서 마킹
  2. 마킹되지 않은 객체를 Heap에서 제거 (Sweep이라 부름)
  3. compact를 하는 GC라면, 단편화 된 메모리를 정리

1) Minor GC 과정

old Generation에 비해 상대적으로 작기 때문에 메모리 상의 객체를 찾아 제거하는데 적은 시간이 걸린다. (작은 공간에서 데이터를 찾으니까)

2.에서 살아남은 객체가 첫 Survivor 영역으로 이동
첫 Survivor 영역 포화 -> Mark and Sweep으로 살아남은 객체가 두번째 Survivor 영역으로 이동
일정 횟수(age) 이상 살아남은 객체를 Old Generation 영역으로 이동(이것을 Promotion 이라고 한다.)

  1. 처음 생성된 객체는 Young Generation 영역의 일부인 Eden 영역에 위치

  1. 객체가 계속 생성되어 Eden 영역이 꽉차게 되고 Minor GC가 실행
    Stop the world -> Mark and Sweep 실행

  1. Mark 동작을 통해 reachable 객체를 탐색
  • Mark: 사용되는 메모리와 사용되지 않는 메모리를 식별되는 작업

  1. Eden 영역에서 살아남은 객체는 1개의 Survivor 영역으로 이동

  1. Eden 영역에서 사용되지 않는 객체(unreachable)의 메모리를 해제(sweep)
  • sweep: Mark 단계에서 사용되지 않음으로 식별된 메모리를 해제하는 작업

  1. 살아남은 모든 객체들은 age값이 1씩 증가

    age: Survivor 영역에서 객체의 객체가 살아남은 횟수를 의미하는 값이며 Object Header에 기록된다. 임계값에 다다르면 Old 영역으로 이동 (age의 기본 임계값은 31)

Survivor 영역에 모두 데이터가 존재하거나, 모두 사용량이 0이라면 현재 시스템이 정상적인 상황이 아니라는 반증이 된다.

  1. 또다시 Eden 영역에 신규 객체들로 가득 차게 되면 다시한번 minor GC 발생하고 mark 한다

  2. marking 한 객체들을 비어있는 Survival 1으로 이동하고 sweep

  3. 다시 살아남은 모든 객체들은 age가 1씩 증가

  1. 반복

2) Major GC 과정

Major GC: Old Generation에 Young Generation에 의해 시작되었으나, GC 과정 중에 제거되지 않은 경우 age 임계값이 차게되어 이동된 값이 계속 Promotion되어 Old 영역의 메모리가 부족해지면 발생

  • Old 영역에 할당된 메모리가 허용치를 넘게 되면 Old 영역에 있는 모든 객체들을 검사하여 참조되지 않는 객체들을 한꺼번에 삭제하는 Major GC가 실행

  1. 객체의 age가 임계값(여기선 8로 설정)에 도달하게 되면,

  1. 이 객체들은 Old Generation 으로 이동된다. 이를 promotion 이라 부른다.

  1. 위의 과정이 반복되어 Old Generation 영역의 공간(메모리)가 부족하게 되면 Major GC가 발생되게 된다.

Stop-The-World

Old 영역의 Major GC는 영역이 크기 때문에 일반적으로 Minor GC보다 시간이 오래걸리며, 10배 이상의 시간을 사용 여기서 본문 초반에 소개했던 Stop-The-World 문제가 발생

  • Major GC가 일어나면 오랜시간 Thread가 멈추고 Mark and Sweep 작업을 해야 해서 CPU에 부하를 주기 때문에 멈추거나 버벅이는 현상이 일어나기 때문
  • GC의 성능 개선을 위해 튜닝을 한다고 하면 보통 Stop The World의 시간을 줄이는 작업을 하는 것

이를 최적화하기 위해 다양한 Garbage Collection 알고리즘이 개발 되었다

GC 알고리즘

: GC 알고리즘은 작성예정입니다.


참고

profile
개발 일지

0개의 댓글