JAVA Garbe Collector

Cori1304·2025년 12월 18일

GC란?

Heap 영역에서 동적으로 할당된 객체 중 더 이상 참조되지 않는 메모리(garbage)를
JVM이 자동으로 탐지하여 제거하는 프로세스이다.

C/C++처럼 개발자가 직접 메모리를 해제하지 않아도 되므로
메모리 관리 부담을 줄일 수 있지만,
GC 역시 비용이 존재하기 때문에 동작 원리를 이해하는 것이 중요하다.

GC 기본 동작 개념

GC는 모든 객체를 무작위로 삭제하지 않는다.
GC Root에서 시작해 참조 관계를 따라가며 “살아있는 객체”를 판단한다.

※ 실제 GC 동작은 GC 알고리즘에 따라 다르며,
Young Generation은 Copy 방식,
Old Generation은 Mark-Sweep(-Compact) 방식이 주로 사용된다.

GC 공통 동작 순서 (개념적 흐름)

  1. Stop-The-World (STW)
    GC를 수행하기 위해 GC 스레드를 제외한 모든 애플리케이션 스레드를 일시 중단한다.
    STW 시간이 길어질수록 서비스 지연(Latency)이 증가한다.

  2. Mark
    GC Root(Stack의 지역 변수, Method Area의 static 변수, JNI 참조 등)에서 시작해
    참조 가능한 객체를 탐색하고 Reachable로 표시한다.

  3. Sweep
    Mark되지 않은(Unreachable) 객체를 제거한다.
    ※ Young GC에서는 개별 Sweep 대신 Copy 방식이 사용된다.

  4. Compact (GC 알고리즘에 따라 수행)
    살아남은 객체를 한쪽으로 이동시켜 메모리 파편화(Fragmentation)를 제거하고
    연속된 메모리 공간을 확보한다.

JVM Heap 메모리 영역

JVM Heap 구조

New / Young Generation

새롭게 생성된 객체가 할당되며, 생명 주기가 짧은 객체가 주로 머무는 영역이다.

  • Eden
    new 키워드로 생성된 객체가 최초로 할당되는 영역
    → Bump-the-pointer 방식으로 빠른 객체 할당이 가능하다.

  • Survivor (From / To)
    Minor GC에서 살아남은 객체가 이동하는 영역
    두 영역 중 하나는 항상 비어 있으며,
    GC마다 살아남은 객체를 다른 쪽으로 복사(Copy)한다.

  • 관련 옵션
    -XX:NewSize, -XX:MaxNewSize

  • 성능 포인트
    Young 영역이 너무 작으면 객체가 빠르게 Old 영역으로 Promotion되어
    Major GC 부하가 증가할 수 있다. (Premature Promotion)

Old Generation (Tenured Generation)

Young Generation에서 여러 번의 GC를 거쳐 살아남은 장수 객체가 저장되는 영역이다.

  • Tenured
    Survivor 영역에서 age 임계값(기본 15)을 초과한 객체가 Promotion 되어 이동한다.

  • 특징

    • 객체 생존율이 높음
    • GC 비용이 큼
    • STW 시간이 길어 성능에 직접적인 영향
  • 관련 옵션
    -Xms, -Xmx (Young 영역을 제외한 나머지)

  • 성능 포인트
    Old 영역이 가득 차면 Major GC 또는 Full GC가 발생한다.
    Heap이 큰 환경일수록 STW 시간을 줄이는 것이 핵심 튜닝 포인트이다.

Metaspace (Native Area)

Java 8부터 도입된 영역으로, JVM이 로드한 클래스 메타데이터를 저장한다.

  • PermGen vs Metaspace

    • PermGen: Heap 영역 (Java 7 이하)
    • Metaspace: Native Memory 사용 (Java 8+)
  • 특징

    • OS 메모리를 사용하여 PermGen 시절보다 OOM 발생 빈도 감소
    • 무한하지 않으며 설정에 따라 OutOfMemoryError: Metaspace 발생 가능
  • 관련 옵션
    -XX:MetaspaceSize, -XX:MaxMetaspaceSize


자세한 GC 동작 순서

GC는 Heap 전체를 한 번에 정리하지 않고,
Young Generation 중심의 Minor GC
Old Generation 중심의 Major / Full GC로 나뉘어 수행된다.

대부분의 GC는 Minor GC이며,
Major GC는 발생 빈도는 낮지만 비용이 크다.

GC 흐름

객체 생성

애플리케이션에서 객체를 생성하면 Eden 영역에 할당된다.
Eden은 연속된 메모리 구조를 사용하여 빠른 할당이 가능하다.

→ Eden이 가득 차면 Minor GC가 트리거된다.

Minor GC (Young Generation GC)

Young Generation(Eden + Survivor)만을 대상으로 수행된다.

📌 Minor GC 특징

  1. 자주 발생
  2. Copying 기반 → 메모리 파편화 없음
  3. Major GC보다 STW 시간이 짧음

1. Stop-The-World (STW)

  • 모든 애플리케이션 스레드 일시 정지
  • Young 영역만 처리하므로 STW 시간이 비교적 짧다

2. Mark (Reachability 분석)

  • GC Root에서 시작해 Eden과 Survivor 영역의 객체 중
  • 참조 중인 객체만 Reachable로 표시

3. Copy (Young GC의 핵심)

  • Reachable 객체를 Eden → Survivor(To)로 복사
  • From 영역의 살아있는 객체도 함께 복사
  • 이 과정에서 객체 age 증가
  • Eden과 From 영역은 통째로 비워진다

4. Promotion

  • age 임계값을 초과한 객체는 Old Generation으로 이동
  • Survivor 공간이 부족해도 강제로 Promotion 발생 가능
  • Old 영역에 공간이 없으면 Promotion Failure → OOM 발생 가능

→ Premature Promotion은 Major GC를 앞당기는 주요 원인이다.

Major GC / Full GC (Old Generation GC)

Old Generation을 대상으로 수행되며,
상황에 따라 Heap 전체를 정리하는 Full GC로 확장될 수 있다.

📒 실무에서는 Major GC와 Full GC를 혼용해 부르기도 하지만, 엄밀히는 Full GC는 Heap 전체(Young + Old + Metaspace)를 대상으로 한다.

📌 Major / Full GC 특징

  • 발생 빈도 낮음
  • STW 시간이 길어 서비스 지연 유발
  • GC 튜닝의 핵심 대상
  • CMS, G1, ZGC, Shenandoah 등은 STW 최소화를 목표로 설계됨

1. Stop-The-World (STW)

  • Minor GC보다 훨씬 긴 STW 발생

2. Mark

  • GC Root부터 Heap 전체를 스캔
  • 살아있는 객체를 Reachable로 표시

3. Sweep

  • Unreachable 객체 제거

4. Compact (알고리즘에 따라)

  • 살아남은 객체를 한쪽으로 밀어 메모리 파편화 제거
  • 연속된 메모리 공간 확보

GC 종료 후

  • STW 해제 후 애플리케이션 재개
  • GC가 잦거나 Major GC 시간이 길어질 경우

Latency 증가, Throughput 감소로 이어진다.

정리

GC는 자동이지만 공짜는 아니다.
객체 생명 주기를 잘못 설계하면 GC 비용은 그대로 성능 문제로 드러난다.

GC 튜닝의 핵심은

  • Minor GC를 빠르게,
  • Major GC를 최대한 늦게,
  • STW 시간을 최소화하는 것이다.

참고 자료

profile
개발 공부 기록

0개의 댓글