[Java] GC 동작 원리, 종류

나른한 개발자·2025년 12월 26일

f-lab

목록 보기
3/46
post-thumbnail

가비지 컬렉터

가비지 컬렉터는 JVM의 힙 영역에서 동적으로 할당했던 메모리 객체 중 더이상 사용하지 않는 객체들을 주기적으로 제거하여 메모리를 회수하는 역할을 한다. 개발자가 메모리 관리나 누수에 대해 직접 관리하지 않아도 된다.

STW (Stop-The-World)

stop-the-world란 GC를 실행하기 위해 애플리케이션 실행을 잠시 중단하는 것을 말한다. stop-the-world가 발생하면 GC를 실행하는 스레드 외에 모든 스레드가 작업을 멈춘다. 그리고 GC 작업이 끝나면 다시 중단했던 작업을 이어간다.

어떤 알고리즘을 사용하더라도 stop-the-world는 발생하며, 이를 줄이기 위해 GC 튜닝을 하기도 한다.

GC 대상이 되는 힙 영역

GC는 'weak generational hypothesis' 라 불리는 두 가지 전제 조건(가설) 하에 만들어졌다.

  • 대부분의 객체는 금방 접근 불가능(unreachable)한 상태가 된다.
  • 오래된 객체에서 젊은 객체를 참조하는 일은 드물다.

이에 따라 HotSpot VM에서는 힙을 크게 young영역old영역으로 나누었다.

  • young 영역: 생성된 대부분의 객체가 이곳에 위치한다. 대부분 금방 접근 불가능한 상태가 되어 대부분의 객체는 이곳에 위치해있다가 사라진다. 이 영역에 대한 GC를 Minor GC라고한다.
  • old영역: 접근 불가능 상태가 되지 않아 young영역에서 살아남은 객체가 여기로 복사된다. 보통 young영역 보다 크게 할당하고 GC는 young영역보다 적게 발생한다. 이 영역에 대한 GC를 Major GC라고한다.

Young영역은 또 다시 Eden영역과 2개의 Survivor영역으로 나뉜다.

  • Eden영역은 new를 통해 새로 생성된 객체가 위치하는 영역이다. 이곳에서 GC가 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동한다.
  • Eden영역에서 GC가 계속 발생하면 Survivor 영역에 객체가 계속 쌓인다.
  • 하나의 Survivor영역이 가득 차면 그중에서 살아남은 객체를 비어있는 Survivor영역으로 이동하고, 기존 Survivor영역은 비운다.
  • 이 과정을 반복하다가 살아남은 객체를 old영역 으로 이동(Promotion)한다.
  • 객체가 계속 프로모션하여 old영역이 가득 차면 Major GC가 발생한다.

Mark-Sweep / Mark-Summary-Compact
1. Mark-Sweep

  • Mark: GC Root 부터 시작하여 연결된 모든 객체를 추적 & 참조 관계가 살아있는 객체에 마킹
  • Sweep: 힙을 훑으며 마킹되지 않는 객체를 메모리에서 해제. 마킹 되지 않은 객체들이 차지하던 공간을 표시하여 나중에도 사용할 수 있도록 함.
    => 객체를 지우고난 공간이 군데군데 비어있게 되어 메모리 파편화가 발생함. 따라서 일반적으로는 이 객체들을 한곳으로 모아주는 Compact(압축)과정을 추가한 Mark-Sweep-Compact를 더 많이 사용함.

  1. Mark-Summary-Compact
  • Mark: 위와 동일
  • Summary: 각 영역에 밀도를 계산하여 살아있는 객체가 많은 공간과 비어있는 곳이 많은 공간인지를 조사하여 압축 후 객체가 최종적으로 위치할 곳을 결정
  • Compact: summary 에서 결정한 위치로 살아있는 객체를 이동

Minor GC 와 Major GC

Minor GC는 Young 영역에서 객체가 사라지는 것이다. Young 영역은 Old 영역보다 일반적으로 크기가 작기 때문에 GC가 짧은 시간내에 종료되어 애플리케이션 성능에 영향을 주지 않는다.

하지만 Major GC는 보다 더 큰 영역에서 실행되고 속도가 더 느리다.

GC 종류

Serial GC

  • 서버의 CPU 코어가 1개일 때 개발된 GC이다.
  • 싱글 스레드로 처리되어 STW가 길다.
  • Minor GC에는 위에서 설명한 것 처럼 Mark-Sweep 방식을 쓰고, Major GC에는 Mark-Sweep-Compact 알고리즘을 사용한다.
  • 메모리와 CPU 코어 개수가 적을때 사용할 수 있지만 실운영 서버에는 사용하면 안된다.

Parallel GC

  • 기본적인 알고리즘은 Serial GC와 같지만 Young 영역의 Minor GC를 멀티 스레드로 실행된다. (Old 영역은 싱글 스레드)
  • Serial GC 보다 STW 시간이 짧다.

Parallel Old GC

  • Parallel GC를 개선한 버전으로, Old 영역도 멀티 스레드로 GC를 수행한다.
  • Mark-Summary-Compact 방식을 사용한다.

Concurrent Mark Sweep GC

  • 애플리케이션 스레드와 GC 스레드가 동시에 실행되어 STW를 최대한 줄이기 위해 고안된 GC
  • GC 대상을 파악하는 과정이 복잡하여 다른 GC 대비 CPU 사용량이 높고 메모리 파편화 문제가 있다.
  • Java14에서는 사용이 중지되었다.

G1 GC

  • Java9+ 버전의 디폴트 GC
  • 기존 GC 알고리즘은 Young, Old 영역으로 나누어 실행했지만, G1GC에서는 전체 Heap 영역을 체스판 처럼 나눈 Region이라는 영역으로 나누어 실행한다.
  • 상황에 따라 Eden, Old, Young 등의 영역으로 고정이 아닌 동적으로 부여한다.
  • Garbage로 가득한 영역을
    빠르게 회수하여 빈 공간을 확보하여 GC 빈도가 줄어든다.
  • 일일이 메모리를 탐색하여 객체를 제거하는 방법이 아닌 메모리가 가득차있는 영역을 우선적으로 GC 대상으로 인식한다.
  • 전체 메모리가 아닌 영역(region)별 로 탐색하고 GC가 일어난다.
  • 살아남은 객체들을 다음 세대의 region으로 이동하는 객체 대피 과정이 있으며, 이때 멈춤 현상(STW)가 일어난다. (이동 시킨 후 해당 객체를 참조하고 있던 포인터 정보를 새로운 주소로 업데이트)
  • 객체 대피로 메모리 파편화를 최소화한다.

Shenandoah GC (셰넌도어 GC)

  • Java12에 릴리즈된 GC이다.
  • 힙 크기에 상관없이 STW시간을 최소화하는 것을 목적으로 한다.
  • g1gc 와 마찬가지로 region을 사용한다.
  • Forwarding Pointer 등을 이용해, 객체를 옮기는 중에도 앱이 멈추지 않고 접근할 수 있게 설계되어 있다.
  • CMS가 가진 단편화와 g1이 가진 pause의 문제를 해결한다.
  • 다만 지연 시간을 최소화하기 위해 CPU자원을 더 많이 할당하고 로드 배리어(객체 참조 시 마다 이동한 객체인지 확인하는 과정)를 하기 때문에 애플리케이션 성능이 부담이 간다.
  • 대용량 힙을 사용하며 실시간 응답이 중요한 경우엔 적합, 그 외 단순 배치 작업처럼 처리량이 중요한 경우에는 parallel, g1gc가 더 적합

Z GC

  • java 15에 릴리즈 되었다.
  • 대량의 메모리를 낮은 지연시간(low latency)으로 처리하기 위해 고안된 GC이다.
  • G1의 메모리 영역의 크기는 고정적인데 비해, Z GC에선 Z Page라 불리는 동적인 크기의 영역을 사용한다. (2MB의 배수의 동적인 크기로 운영됨)
  • 객체 크기에 따라 크기를 유동적으로 정하여 효율적으로 공간 관리를 할 수 있고 메모리 파편화를 최소화할 수 있다.
  • 객체 주소의 일부 비트에 객체 상태(이사갔는지, 마킹 여부 등)표시하는 Colored Pointer를 한다.
  • 앱이 객체에 접근할 때 Colored Pointer를 체크하여 이사중이면 즉시 올바른 주소로 업데이트한다. (로드배리어) 따라서 애플리케이션을 중지하지 않고 처리할 수 있다.(다만 GC Roots를 식별하거나 스레드별로 객체 상태를 동기화하기 위한 아주 짧은 Pause는 필수적.)
  • 힙 크기가 증가하더라도 STW가 최대 1ms를 넘지 않는다.(자바 16+ 기준)

Java Garbage Collection
Java Reference와 GC
가비지 컬렉션 동작 원리 & GC 종류 총정리

profile
Start fast to fail fast

0개의 댓글