GC (Garbage Collection)

Garbage Collection

JVM의 Garbage Collection에 대해서 알아봅니다.


Goal

  • JVM의 실행엔진 안에 속해있는 GC에 대해서 알아봅니다.
  • GC의 동작방식에 대해서 알아봅니다.
  • GC의 알고리즘 종류에 대해서 알아봅니다.

What is GC

사용되지 않는 객체에 대한 메모리 할당을 자동으로 해제 시켜주는 기술을 이야기합니다.

  • 기본적으로 Java Heap 영역의 메모리를 다룹니다.

How Working

가비지 컬렉션 과정 - Generational Algorithm

새롭게 생긴 객체는 금방 없어지고, 오래 버틴 객체는 오래 버틴다는것을 기반으로 가져갑니다.

java7

Untitled 1

java8

image

  • Heap은 Young영역Old영역 으로 메모리를 분할하고, 신규로 생성되는 객체는 Young 영역에 보관합니다.
  • Young영역에서 객체가 사라질때를 Minor GC, Old영역에서 객체가 사라질떄를 Major GC라고 부릅니다.
  • Eden space에 객체를 채우다가 가득차면 Minor GC 가 발생합니다

Young 영역

  • Eden
  • Survivor (2개)

image

image

  • 처음 생성된 객체는 Eden 영역에 위치합니다. Eden 영역이 가득차면 Minor GC가 시작됩니다.

image

  • 먼저 참조된 이력이 있는 객체들은 age를 높여 s0 에 이동을 시키고, 그렇지 않은 객체들은 제거됩니다.

image

  • 또 다음 Minor GC가 일어나면, s0와 Eden에 있던 객체중 참조된 것은 s1으로 이동하고 나머지 공간인 s0과 Eden에 있는 객체들은 제거됩니다.
  • s0와 s1는 번갈아가서 반복되기 때문에, s0이 생존공간이 되고 s1, Eden의 객체들이 삭제되는 경우도 있을 수 있습니다.

image

  • 일정 age가 넘어간 객체들은 old 영역으로 이동하게 됩니다.
  • 이때 age 기본값은 31입니다. 해당 Age를 기록하는데 사용되는 bit가 6bit이기 때문입니다.

이외의 GC 알고리즘 종류

Reference Counting Algorithm

객체가 참조되어지고 있는 Count가 몇개인지를 확인하고 GC에서 지울지를 결정합니다.

  • 0개가 되는 객체들은 메모리해제의 대상이 됩니다.

Mark and Sweep Algorithm

Reference Counting순환참조를 해결하지 못한다는 단점이 있습니다. 이를 개선하기 위해 나온 방법입니다.

  • Root Set 로부터 접근 가능한 객체를 전부 Marking 해둡니다. 중복 되지 않게 Flag같은것을 심어둡니다.
  • Marking되지 않은 객체들의 메모리를 제거합니다.
  • 하지만 메모리 중간중간이 비어있는 단편화 현상이 발생합니다.

Mark and Sweep Compaction Algorithm

메모리 단편화 현상을 해결하기 위해 나온 방법입니다.

  • sweep 이후 단편화가 발생한 공간을 이어 붙입니다.
  • 과거 디스크 모음조각을 하던 시절을 연상하면 기억하기 쉽습니다.
  • 하지만 해당 부분을 이어붙이는데 들어가는 오버헤드가 발생합니다.

Copying Algorithm

Heap을 Active영역과 InActive 로 나누어서 관리합니다.

  • Generational Algorithm 의 과거 형태입니다.
  • 이 알고리즘도 단편화문제를 해결하고자 나온 알고리즘입니다.
  • Heap영역을 절반으로 나눈뒤, Active영역에만 메모리를 할당합니다.
  • Active 영역이 다 차게되면, 살아남는 객체들은 InActive 영역으로 Copy합니다.
  • 이후 Active 영역의 Object들을 삭제합니다.
  • Active와 InActive의 위치를 서로 바꿉니다.
  • 하지만 힙의 절반영역밖에 쓰지 못하는 단점과, Copy과정에 들어가는 오버헤드가 있습니다.

GC 종류

GC별 동작 방식을 정리한 내용은 글을 분리해서 작성할 예정입니다.

  • Serial GCL (mark sweep compact)
  • Parallel GC: java8 디폴트 (쓰레드 병렬처리)
  • Parallel Old GCL: (Mark Summary Compact)
  • CMS: (stop the world는 짧지만, 메모리 CPU 낭비가 심한 GC)
  • G1GC: Java11 디폴트 (큰 메모리에 적합한 GC, 이전에는 Heap이 작았기 때문에 순차적으로 접근해도 큰문제가 없었음)
    • 기존의 young old 영역의 heap 형태는 잊어야 합니다.
    • 영역이 다차면 다른 영역에 객체를 할당하고 GC 진행
  • Z1 GC: (Java11 부터 일부 도입)

Reference