Java Garbage Collection

Chunbae·2025년 2월 4일
0

Java

목록 보기
10/11
post-thumbnail

Garbage Collection이란?

일명 GC는 자바의 메모리 관리 방법 중의 하나로 JVM의 Heap영역에서 동적으로 할당했던 메모리 중 필요없어진 메모리 객체를 모아 주기적으로 제거하는 프로세스를 말합니다.

C, C++언어는 이러한 가비지 컬렉션이 없어 수동으로 메모리의 할당과 해제를 일일이 설정해야 하고,
Java이외에도 Python / Go / JavaScript 등 많은 프로그래밍 언어에서 GC가 기본으로 내장되어있습니다.

GC의 대상

GC는 특정 객체가 처리되어야 하는지 아닌지 판단하기 위해서 "도달성", "도달능력"이라는 개념을 적용하여 판단합니다.
객체에 Reference가 있다면 Reachable로 분류하고, 객체에 유효한 Reference가 없다면 Unreachable 로 분류해 수거를 진행합니다.

  • Reachable : 객체가 참조되고 있는 상태.
  • UnReachable : 객체가 참조되지 않는 상태.

class Main {

    public static void main(String[] args) {

        String str = new String("Hello GC");

        str = null; // 더 이상 참조되지 않음 → GC 대상

        System.gc(); // GC 요청 (실제 동작 보장 X)
    }
}
	



GC의 동작 방식

Java의 GC 알고지르즘은 크게 3단계로 동작하게 됩니다.
대상이 될 객체를 식별(Mark) 후 제거(Sweep)하고 객체가 제거되어 파편화 된 메모리 영역을 채워나가는 작업(Compack)를 진행합니다.

  1. Mark

    • 사용중인 객체와 사용되지 않는 객체를 구분하는 단계
      • reachableUnreachable를 판단하는 단계
    • 참조 되고 있는 객체는 유지, 그렇지 않으면 제거 대상으로 설정.
  2. Sweep

    • Mark단계에서 불필요한 객체로 판별된 것들을 제거
  3. Compack(압축단계, 필요시 설정을 통해 수행하게됨)

    • 객체를 연속된 공간으로 이동하여 단편화를방지.
    • 메모리를 효율적으로 사용하기 위해 수행
      - 예를 들면 디스크조각모음.



Heap영역의 구조

Java Heap은 GC 성능 최적화를 위해 생성된 상황에 맞춰 분류를 진행하게 됩니다.
Young / Old Generatin, Measpace로 구분합니다.

Young영역보다 Old영역이 더 크게 할당되는 이유는 Young영역은 수명이 짦은 객체들이 주로 가기 때문에 GC가 활발하게 동작하지만 Old영역의 경우에는 큰 객체 or 수명이 긴 객체들이 존재하기 때문에 보다 큰 영역을 차지하고 있습니다.



Young Generation (Minor GC)

  • 프로그램 실행 중 가장 많은 객체가 생성되는 영역.
    - 대부분의 객체는 금방 Unreachable상태가 되기 때문에 Young에서 GC의 대상이 된다.
  • 해당 영역에서 가장 오래 살아있는 객체는 Old Generatin으로 이동하게 됨.

[!NOTE]
Young영역을 세부적으로 분류하면 다음과 같습니다.

  • Eden : 새롭게 생성된 객체가 저장되는 공간
  • Survivor S0, S1 : Eden에서 살아남은 객체가 이동하는 영역.

Old Generatin (Major / Full GC)

  • Young영역에서 살아남은 객체가 저장되는 영역.
    - Young영역보다 크게 할당되며 영역의 크기가 큰 만큼 GC는 적게 발생함.

  • Old영역이 가득 차게 되면 GC가 발생하여 메모리를 정리함.
    - Old영역의 GC는 Major / FUll GC라고 명칭하기도 함.




GC의 알고리즘 종류

GC를 수행하기위해서는 Stop The World가 발생하게 되고 이로 인해 애플리케이션이 중지되는 문제점이 발생하게 되었습니다. 또한 자바의 발전으로 Heap영역이 커지면서 지연현상이 두드러지게되었고 이로인해 GC의 다양한 알고리즘이 개발되게 되었습니다.

STW - Stop the World
GC를 수행하기 위해 JVM이 프로그램 실행을 멈추는 현상을 의미합니다.
GC가 동작하는 동안 GC관련 Thread를 제외한 모든 Thread를 중지하게 되어 서비스 이용에 차질이 생길 수 있습니다.

Serial GC

  • 하나의 스레드로 동작하여 애플리케이션 실행이 일시 중지(STW) 됨.
  • 싱글 스레드로 동작하기 때문에 STW의 시간이 가장 오래 걸림.
  • 실무에서 사용하는 경우는 없음.

Parallel GC

  • Java 8에서 기본으로 설정된 GC.
  • Young영역에서는 Minor GC를 멀티스레드로 동작하고 Old에서는 싱글 스레드로 동작함.

CMS GC

  • Concurrent Mark-Sweep GC의 약자로 실행과 GC를 동시에 수행하여 STW시간을 줄임.
  • GC중에도 애플리케이션 실행 가능.
  • 단점으로는 CPU를 많이 사용하기 때문에 성능저하가 발생할 수 있음.

G1 GC

  • JDK 9버전의 기본 GC.
  • 기존에 분리되어 있던 Heap영역(Young/Old)를 하나의 Heap으로 보고 Region단위로 분류하여 동작함.
    - 분할하여 Eden, Survivor, old영역을 동적으로 부여해 빠른 공간회수 가능.
  • 애플리케이션의 성능을 유지하면서 짧은 GC시간을 보장함.

ZGC

  • /ms 이내의 지연시간을 목표로하는 GC로 JDK 11이후에 나옴.
  • 초대형 Heap에도 낮은 지연시간을 보장하고 GC 동작 중에도 애플리케이션이 원할이 실행됨.

JDK 21 ~ 23버전에서 사용중인 GC 알고리즘은 G1 GC를 사용하고 있습니다.
JDK 21이후에 Generational ZGC가 생겨났지만 아직까지는 기본 GC로 설정되어 있지는 않다고합니다.

profile
말하는 감자

0개의 댓글