JVM의 GC동작, 몇 종류의 GC

1 분 소요

JVM 의 GC 과정

  1. Garbage Collector가 Stack의 모든 변수를 스캔하면서 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다.
  2. Reachable Object가 참조하고 있는 객체로 찾아서 마킹한다.
  3. 마킹 되지 않은 객체를 Heap에서 제거한다.

위에서 1,2 - Mark, 3 - Sweep, 그래서 Mark & Sweep GC라고도 한다.

JVM의 Heap 영역은 Young 영역과 Old 영역으로 나누어진다.

Young 영역

Young 영역은 3개의 영역으로 나뉜다.

  • Eden 영역
  • Survivor 영역(2개)
  1. 새로 생성한 객체는 Eden영역에 위치한다.
  2. Eden 영역에 GC가 한번 발생한 후 살아남은 객체는 Survivor 영역(Survivor A)으로 이동한다.
  3. 그 이후로도 Eden 영역에서 GC가 발생하면 살아남은 객체는 Survivor A로 계속 이동하며 쌓인다.
  4. Survivor A영역이 가득 차게 되면 그 중 살아남은 객체를 다른 Survivor 영역(Survivor B)으로 이동한다. 그리고 Survivor A영역은 아무 데이터도 없는 상태가 된다.
  5. 1~4 과정을 반복한다.
  6. Survivor 영역이 가득 차서 다른 Survivor 영역으로 이동하면서 Age라고 하는 값들이 증가한다.
  7. 이 Age값들이 특정 값 이상이 되면 Promotion이라고 하는 것이 일어난다.
  8. 특정 Age 이상이 된 객체들은 Promotion으로 Old Generation 영역으로 이동하게 된다.
  9. 이 과정을 거쳐 Old Generation 영역이 가득찰 때 Major GC가 발생한다.
  10. 이 전체적인 과정을 반복하며 Garbage Collector가 메모리 관리를 한다.

** Survivor 영역 중 하나는 반드시 비어 있는 상태로 남아 있다.

그림으로 살펴보자

GC

위와 같은 Minor GC과정을 반복하게 된다.

Promotion

Promotion - 2

Promotion이 일어나고 Old Generation 영역이 채워지다가 가득차게 되면 아래 그림 처럼 Major GC가 발생한다.

Major GC

몇 가지 GC의 종류

CMS GC (Concurrent Mark-Sweep)

Young 영역의 GC는 위의 설명과 같다.

Old 영역의 GC는 아래와 같다.

  1. Mark: 살아있는 객체를 찾는 단계(Stop-the-world)
  2. Concurrent Mark: 방금 살아있다고 확인한 객체에서 참조하고 있는 객체를 따라가면서 확인.(다른 쓰레드가 실행 중인 상태에서 동시 진행)
  3. Remark: Concurrent Mark 수행하면서 다른 쓰레드에 의해 새로 추가되거나 참조가 없어진 객체 확인(Stop-the-world)
  4. Concurrent Sweep: Garbage 정리(다른 쓰레드 실행 중)

CMS GC는 Stop-The-World 시간이 짧다는 장점이 있다.

단점은 메모리와 CPU를 더 많이 사용한다. Compaction 단계가 없다.

G1GC (Garbage First Garbage Collector)

전체 Heap을 체스판처럼 여러 영역으로 나누어 관리한다.

G1GC

그림에서 하늘색 영역은 young generation이다. young generation이 가득차면 GC가 발생한다. 그리고 GC가 발생할 때 살아 있는 객체들은 복사된다.(이 과정에서 compact 효과도 있다.)

G1은 살아있는 객체를 새 영역에 복사할때만 애플리케이션을 멈춘다.

GC를 위해 Heap 전체를 찾지 않기 위해 G1은 영역의 참조를 관리할 목적으로 remember set을 만들어 사용한다.

궁금한 점

  • JVM에서 GC가 일어날 때 한 트랜잭션이 끝났는지 어떻게 확인하고 Stop-The-World 하는가?
    • GC가 돌 때 나머지 Thread들의 상태를 저장하고, GC가 돈다.
    • 하지만 Transaction 관점에서 보면, 만약 DB에 insert하는 transaction 중간에 GC가 끼게된다면, timeout이 발생할 가능성은 생긴다.
    • GC의 정책이 변경된다고 했을 때 예상치 못한 에러가 발생할 가능성이 있다.

참고자료

태그: ,

카테고리:

업데이트:

댓글남기기