ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] Garbage Collection
    CS/개발 언어 (JAVA) 2021. 4. 21. 13:18

    stop-the-world

    GC을 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것이다.

    stop-the-world가 발생하면 GC를 실행하는 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈춘다.

    대개의 경우 GC 튜닝이란 이 stop-the-world 시간을 줄이는 것이다.

     

    Java는 프로그램 코드에서 메모리를 명시적으로 지정하여 해지하지 않기 때문에 가비지 컬렉터(Garbage Collector)가 더 이상 필요없는 객체를 찾아 지우는 작업을 한다. 이 가비지 컬렉터는 두 가지 가정하에 만들어졌다.

    대부분의 객체는 금방 접근 불가능 상태(unreacheable)가 된다.

    오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다.

     

    이 가정의 장점을 최대한 살리기 위해 HotSpot VM에서는 크게 2개로 물리적 공간을 나누었다.

    Young Generation 영역

    새롭게 생성된 객체의 대부분이 여기에 위치한다.

    대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 많은 객체가 Young 영역에서 생성되었다가 사라진다.

    이 영역에서 객체가 사라질 때 Minor GC가 발생한다고 한다.

    Old Generation 영역

    접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 여기로 복사된다.

    대부분 Young 영역보다 크게 할당되며 크기가 큰 만큼 Young 영역보다 GC가 적게 발생한다.

    이 영역에서 객체가 사라질 때 Major GC가 발생한다고 한다.

     

    Old 영역에 있는 객체가 Young 영역에 있는 객체를 참조하는 경우 처리?

    Old 영역에는 512바이트 덩어리(chunk)로 되어 있는 카드 테이블(card table)이 존재한다.

    카드 테이블에는 Old 영역에 있는 객체가 Young 영역에 있는 객체를 참조할 때마다 표시를 하고, Young 영역에서 GC가 실행 될 때 Old 영역에 있는 모든 객체들의 참조를 확인하지 않고 이 카드 테이블만 뒤져서 GC 대상인지 식별한다.

     

    Young 영역에 대한 GC

    • Young 영역은 3개의 영역으로 구성된다.
      • Eden 영역
      • Survivor 영역(2개)
    • 각 영역의 처리 절차
      • 새로 생성된 대부분의 객체는 Eden 영역에 위치한다.
      • Eden 영역에서 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동한다.
      • Eden 영역에서 GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor 영역으로 객체가 계속 쌓인다.
      • 하나의 Survivor 영역이 가득 차게 되면 그 중에서 살아남은 객체를 다른 Survivor 영역으로 이동시킨다. 그리고 가득 찬 Survivor 영역은 아무 데이터도 없는 상태가 된다.
      • 이 과정을 반복하다가 살아남은 객체는 Old 영역으로 이동하게 된다.

     

    Old 영역에 대한 GC

    Old 영역은 기본적으로 데이터가 가득차면 GC를 실행한다.

    Serial GC(-XX:+UseSerialGC)

    • mark-sweep-compact 알고리즘 사용
      • Old 영역에서 살아있는 객체를 식별 (Mark)
      • 힙(heap)의 앞 부분부터 확인하여 살아있는 것만 남긴다 (Sweep)
      • 각 객체들이 연속적으로 쌓이도록 힙의 가장 앞 부분부터 채운다. (Compact)

    Parallel GC(-XX:+UseParallelGC)

    • Serial GC와 동일한 알고리즘을 사용하지만 Serial GC는 GC를 처리하는 스레드가 하나인 것에 비해, Parallel GC는 GC를 처리하는 스레드가 여러 개이다.

    Parallel Old GC(-XX:+UseParallelOldGC)

    • mark-summary-compact 알고리즘 사용
    • mark와 compact 단계는 동일하고, summary 단계에서 앞서 GC를 수행한 영역에 대해서 별도로 살아있는 객체를 식별한다는 차이가 있다.

    CMS GC(-XX:+UseConcMarkSweepGC)

    • initial mark 단계 : 클래스 로더에서 가장 가까운 객체 중 살아 있는 객체만 찾는 것에서 끝낸다.
    • concurrent mark 단계 : 방금 살아있다고 확인한 객체에서 참조하고 있는 객체를 따라가면서 확인한다. (다른 스레드가 실행 중인 상태에서 동시 진행)
    • remark : concurrent mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다.
    • concurrent sweep : 쓰레기를 정리하는 작업 실행

    G1 GC(-XX:+UseG1GC)

    • Young의 세 가지 영역에서 Old 영역으로 이동하는 단계가 사라진 GC 방식
    • 바둑판의 각 영역에 객체를 할당하고 GC를 실행한다. 그러다가 해당 영역이 꽉 차면 다른 영역에서 객체를 할당하고 GC를 실행한다.

     

    참조 사이트

    Java Gargabe Collection

    Garbage Collection 모니터링

    Gargabe Collection 튜닝

    G1 GC 상세

    'CS > 개발 언어 (JAVA)' 카테고리의 다른 글

    [JAVA] Reactive Streams  (0) 2021.05.16
    [JAVA] 자바 가상 머신 (Java Virtual Machine)  (0) 2021.05.12
    [JAVA] JVM Memory  (0) 2021.04.22
    스프링의 핵심 3요소  (0) 2021.04.05
    다형성 (Polymorphism)  (0) 2021.04.05

    댓글

Designed by Tistory.