[JVM] Garbage Collector (1) 개념 및 동작원리

itonse·2024년 5월 30일
0

JAVA

목록 보기
16/19

가비지 컬렉션이란?

프로그래밍을 하다 보면 유효하지 않은 메모리인 가비지(Garbage)가 발생합니다. C언어의 경우 free() 함수를 사용해서 직접 메모리를 해제해줘야 하지만, Java나 Kotlin에서는 직접 메모리를 해제하지 않습니다. 이는 JVM의 가비지 컬렉터(GC)가 불필요한 메모리를 자동으로 정리해주기 때문입니다.


아래는 객체 생성과 참조 과정에서의 가비지 컬렉션의 대상이 되는 코드의 예시를 보여줍니다.
Person person = new Person();
person.setName("Sam");
person = null;   // null을 사용하며 불필요한 데이터임을 명시
// 이전에 생성된 Person 객체에 대한 참조를 끊습니다. 이제 이 객체는 더 이상 접근할 수 없으며, 가비지 컬렉션의 대상이 됩니다.

person = new Person();
person.setName("Sam");



Minor GC와 Major GC

Heap 메모리

  • 힙 메모리는 런타임 시 자바 클래스 인스턴스와 배열이 할당되는 영역입니다.
  • JVM의 가비지 컬렉터(Garbage Collector)에 의해 관리되며, 더 이상 사용되지 않는 객체의 메모리 할당과 해제를 자동으로 처리합니다.
  • 힙 메모리의 크기는 JVM 커맨드 라인 옵션(-Xmx: 최대 힙 크기, -Xms: 초기 힙 크기)을 사용하여 설정할 수 있습니다.

JVM의 Heap 메모리는 다음과 같은 가정을 기반으로 설계되었습니다.
  1. 대부분의 객체는 금방 접근 불가능한 상태(unreachable)가 된다.
  2. 오래된 객체에서 새로운 객체로의 참조는 매우 드물다.

이러한 가정에 따라 Heap 메모리의 영역은 Young Generation과 Old Generation으로 나뉘며, 각 영역은 다른 가비지 컬렉션 방식(Minor GC와 Major GC)을 사용하여 메모리를 관리합니다.


Heap 메모리 영역 - Young Generation

역할: 새롭게 생성된 객체가 할당되는 영역입니다.

특징: 대부분의 객체가 금방 접근 불가능한 상태(unreachable)가 되기 때문에, 많은 객체가
Young 영역에 생성되었다가 빠르게 사라집니다.

GC 유형: Young Generation에 대한 가비지 컬렉션을 Minor GC라고 부릅니다.


Heap 메모리 영역 - Old Generation

역할: Young Generation에서 살아남은 객체가 복사되는 영역입니다.

특징: Young Generation보다 큰 크기로 할당되며, 그만큼 가비지가 적게 발생합니다.

GC 유형: Old Generation에 대한 가비지 컬렉션을 Major GC라고 부릅니다.


Old Generation이 Young Generation보다 크게 할당되는 이유?

  1. 객체 생애 주기: Young Generation의 객체들은 대부분 단명하므로 큰 공간이 필요하지 않습니다.
    반면에 Old Generation은 상대적으로 오래 살아남은 객체들을 수용하므로 더 큰 공간이 필요합니다.

  2. 큰 객체 할당: 큰 객체들은 Young Generation 대신 바로 Old Generation에 할당되는 경우가 많습니다.



가비지 컬렉션의 동작 방식

JVM의 가비지 컬렉션은 Young Generation과 Old Generation의 메모리 구조에 따라 다르게 작동하지만, 기본적으로
두 단계를 따릅니다.

  1. Stop the Wold

    • GC를 실행하기 위해 JVM이 애플리케이션의 실행을 멈춥니다. GC를 실행하는 스레드를 제외한
      모든 스레드의 작업이 중단되고, GC가 완료되면 작업이 재개됩니다.
  2. Mark and Sweep

    • Mark: 사용되는 메모리와 사용되지 않는 메모리를 식별합니다.
    • Sweep: Mark 단계에서 사용되지 않음으로 식별된 메모리를 해제합니다.

  • Java 8 HotSpot JVM 구조 이미지

Minor GC의 동작 방식

Young Generation은 Eden 영역과 두 개의 Survivor 영역(S0, S1)으로 나뉩니다.

  • Eden 영역: 새로운 객체가 할당되는 초기 공간.
  • Survivor 영역 (S0, S1): 최소 한 번의 GC를 살아남은 객체가 존재하는 공간.

이미지 출처

동작 과정

  1. 객체 생성: 객체가 새롭게 생성되면 Eden 영역에 할당됩니다.
  2. Eden 영역이 꽉 찼을 때: Eden 영역이 꽉 차면 Minor GC가 발생합니다.
    • 사용되지 않는 메모리는 해제됩니다.
    • Eden 영역의 객체 중 살아남은 객체는 Survivor 영역(S0 또는 S1)으로 이동합니다. 이때 하나의 Survivor 영역은 항상 비어 있어야 합니다.
  3. Survivor 영역 간의 이동: 살아남은 객체는 S0에서 S1 또는 S1에서 S0으로 이동합니다.
    • 이 과정에서 두 Survivor 영역 중 하나는 항상 비어 있는 상태를 유지합니다.
  4. Old Generation으로 이동: 여러 Minor GC 사이클을 거치면서 Survivor 영역에 오래 남아 있는 객체는 Old Generation으로 이동됩니다.

Major GC의 동작 방식

Young Generation에서 오래 살아남은 객체는 Old Generation으로 이동됩니다. Major GC는 Old Generation의 메모리가 부족해지면 발생합니다.

동작 과정

  1. 객체 이동: Young Generation에서 살아남은 객체가 Old Generation으로 이동됩니다.
  2. Old Generation 메모리 부족: Old Generation의 메모리가 부족해지면 Major GC가 발생합니다.
    • Major GC는 Old Generation의 메모리를 청소합니다.
    • 이 과정은 일반적으로 Minor GC보다 시간이 오래 걸립니다.

Full GC

  • Young Generation과 Old Generation을 동시에 처리하는 GC를 Full GC라고 합니다.
  • 전체 힙 메모리를 청소하며, 가장 오래 걸리는 GC 과정입니다.



요약

Young Generation: 새로 생성된 객체가 할당되며, 단명 객체가 많습니다.

Old Generation: Young Generation에서 살아남은 객체가 이동되며, 상대적으로 오래된 객체를 수용합니다.

Minor GC: 주로 Young 영역에서 발생하며, Eden 영역이 꽉 차면 실행됩니다.

Major GC: 주로 Old Generation에서 발생하며, Young Generation의 메모리가 부족해지면 실행됩니다.

Stop The World: GC를 실행하기 위해 모든 스레드를 멈추는 과정입니다.

Mark and Sweep: 메모리 사용 여부를 식별(Mark)하고, 사용되지 않는 메모리를 해제(Sweep)하는 단계입니다.


ref.
https://jellili.tistory.com/60
https://gaebalsogi.tistory.com/64
https://mangkyu.tistory.com/118
https://www.codeburps.com/post/memory-footprint-of-the-jvm

0개의 댓글

관련 채용 정보