[GC] 1. G1GC

rin·2021년 9월 29일
5

https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html
https://johngrib.github.io/wiki/java-g1gc/

자바 기술과 JVM

개요

  • JRE(Java Runtime Environment) : JVM(Java Virtual Machine), Java 플랫폼 코어 클래스, Java 플랫폼 라이브러리로 구성
  • JDK(Java Development Kit) : Java Application을 개발하기 위한 도구 모음. JDK를 사용해 Java로 작성된 프로그램을 컴파일하고 JVM에서 실행 할 수 있다.
    추가적으로 어플리케이션을 패키징하고 배포하기 위한 도구도 제공한다.
  • Java API :개발자가 Java Application을 만드는데 사용하는 라이브러리 모음.
    JDK와 JRE는 Java api를 공유한다.
  • JVM(Java Virtual Machine) : 자바 어플리케이션을 클래스 로더를 통해 읽어 들여 자바 api와 함께 실행시킨다. Java와 OS 사이의 중개자 역할을 수행해 Java가 OS에 구애받지 않고 사용가능 하게 해준다. 메모리 관리 및 GC를 수행한다.

JVM 아키텍처

Hotsop Architecture

가장 일반적인 JVM 중 하나로써, 말 그대로 Hot한 Spot을 찾아서 해당 부분에서는 JIT 컴파일러를 사용하는 방법이다.
내부적으로 프로파일링을 통해 핫스팟을 찾아내고, 해당 부분에 대한 네이티브 코드를 생성한다. 이 때 Client 혹은 Server 라인 두 가지 방법 중 하나를 사용한다.

Java 어플리케이션의 실행 중 최적화를 위한 결정을 내리고 기본 시스템 아키텍처를 대상으로 하는 고성능 native machine 명령을 제공한다.

주요 구성 요소에는 Class Loader, Runtime data areas, Execution engine이 포함된다.

성능 튜닝의 중점이 되는 3가지 요소는 Heap, GC, JIT 컴파일러이다.
Heap은 오브젝트 데이터가 저장되는 곳으로써 어플리케이션 시작 시 선택된 GC에 의해 관리된다. 대부분의 튜닝 옵션은 힙의 크기를 조정하는 것과 적절한 GC를 선택하는 것과 관련된다.
JIT 컴파일러도 성능에 큰 영향을 미치나 최신 버전의 JVM에서는 조정할 필요가 거의 없다.

Performance Basics

일반적으로 Java 어플리케이션 튜닝 시 목표는 응답성(responsiveness)이나 처리량(throughput) 중 하나라고 할 수 있다.

Responsiveness

어플리케이션이나 시스템이 요청된 데이터에 얼마나 빨리 응답하느냐를 나타낸다. 이에 중점을 둔 어플리케이션의 경우 긴 일시 중지 시간이 허용되지 않는다. 즉, 단기간에 대응하는 것에 중점을 둔다.

  • 데스크탑 UI가 이벤트에 응답하는 속도
  • 웹사이트가 페이지를 반환하는 속도
  • 데이터베이스 쿼리가 반환되는 속도

Throughput

특정 기간 동안 어플리케이션의 작업량을 최대화하는 것에 중점을 둔다. 이에 중점을 둔 어플리케이션의 경우 긴 일시 중지 시간이 허용된다. 더 긴 시간 동안 벤치마크하는 것에 초점을 두기 때문에 빠른 응답 시간을 고려 사항이 아니다.

  • 주어진 시간에 완료된 트랜잭션 수
  • 배치 프로그램이 한 시간에 완료할 수 있는 작업 수
  • 한 시간에 완료할 수 있는 데이터베이스 쿼리 수

GC별 비교

Parallel GC, CMS

  • Parallel GC
    • old gen의 공간에서만 재확보와 조각 모음(압축)을 진행한다.
    • 짧은 GC 작업으로 분배하여 수행함으로써 전체 처리량을 감소하지만 STW를 크게 단축시킨다.
  • CMS
    • old gen 영역을 동시에 작업한다.
    • 단, 조각 모음(압축)을 진행하지 않으므로 Full GC 시간이 길어지는 문제가 생긴다.

❗️ Full GC란
메모리 전체를 대상으로 하는 GC.
Old 영역이 가득차면 Full GC가 발생한다.

전체 비교표

TypeParalleConcurrentYoung GCTenured GCFeature
Serial GC--SerialSerialBatch processing
Parallel GCYes-ParallelParallelHigh throughput
CMS GCYesYesParallelParallel & Conc.Low Pause
G1 GCYesYesParallelParallel & Conc.Low Pause & High throughput

G1GC

개요

Garbage-First(G1) 컬렉터는 대용량 메모리가 있는 다중 프로세서 시스템을 대상으로 하는 서버-스타일 가비지 컬렉터이다.

  • 높은 처리량과 낮은 Stop-The-World(STW) 지향
  • CMS의 개선안으로 계획됨
  • 쓰레기 비중이 높은 heap region을 집중적으로 수집한다.
  • Java9부터 디폴트로 설정되어 있다.
    • -XX:+UseG1GC옵션을 사용하여 수동으로 활성화할 수 있다.

이전 GC와 비교했을 때, 고정된 메모리 크기의 Young Generation, Old Generation, Permanent Generation 으로 구분됐던 것과 달리 아래와 같이 동일한 크기의 힙 영역(Region) 집합으로 분할한다.

JVM 힙은 2048개의 Region으로 나뉠 수 있으며, 각 Region의 크기는 1MB ~ 32MB 사이로 지정될 수 있다. (-XX:G1HeapResionSize 옵션)

추가적으로 Humongous, Available/Unused 라는 영역이 존재한다.

  • Humongous : Region 크기의 50%를 초과하는 큰 객체를 저장하기 위한 공간. 이 Region에서는 GC 동작이 최적으로 동작하지 않는다.
  • Available/Unused : 아직 사용되지 않은 Region을 의미한다.

G1은 회수 가능한 영역, 즉 쓰레기가 많을 것으로 예상되는 영역에 대한 수집 및 압축이 주가 된다. 이것이 Garbage-First, G1으로 명명된 이유라고 할 수 있다.

G1은 힙의 하나 이상의 Region에서 단일 Region으로 개체를 복사하고 이 과정에서 메모리를 압축 및 해제 시킨다. 이 때 STW 시간을 줄이고 처리량을 늘리기 위해 다중 프로세서에서 병렬로 작동된다.

data structures

Remembered Sets(RSet)

reference를 가진 Object등이 어느 Region에 있는지 알기 위해 사용하는 자료구조
주어진 Region에 대한 참조 개체를 추적한다. 각 Region 당 하나의 RSet이 존재하며 이를 통해 Region의 병렬 및 독립된 수집을 가능하게 한다. RSet이 전체 영역에서 차지하는 비율은 5% 이내이다.
GC 로그에서 이 Reference 정보를 갱신(update)하고 검색하는데 소요되는 시간을 확인 할 수 있다.

객체 참조의 Origin을 왜 알아야하는 지는 Baker's Incremental GC 알고리즘, Baker's Incremental Copying Collector 알고리즘 을 참고하자. Reference를 가진 Object를 찾아 라이브 객체를 복사하는 알고리즘이다.

Collection Sets(CSet)

GC가 수행될 Region 집합
CSet 내의 데이터는 GC 동안 모두 비워진다(복사되거나 이동됨). Region 집합은 Eden, Survivor, Old Generation으로 이루어질 수 있다. CSet이 JVM에서 차지하는 비율은 1% 이내이다.
GC 로그에서 CSet을 선택하고 Processing 후 CSet을 해제하는데 걸린 시간을 확인할 수 있다. Evacuation Pauses와 Mixed GC를 수행할 때 사용하는 자료구조이다.

G1GC 동작 방식

G1 GC에서 Full GC 가 수행될 때는 Initial Mark -> Root Region Scan -> Concurrent Mark -> Remark -> Cleanup -> Copy 단계를 거치게된다.

추가적으로, G1GC는 일시 정지 시간을 줄이기 위해 병렬로 GC 작업을 한다. 각 스레드가 자신만의 region을 잡고 작업하는 방식.

  1. Initial Mark
    Old Region 에 존재하는 객체들이 참조하는 Survivor Region 을 찾는다. 이 과정에서는 STW 현상이 발생하게 된다.
  2. Root Region Scan
    Initial Mark 에서 찾은 Survivor Region에 대한 GC 대상 객체 스캔 작업을 진행한다.
  3. Concurrent Mark
    전체 힙의 Region에 대해 스캔 작업을 진행하며, GC 대상 객체가 발견되지 않은 Region 은 이후 단계를 처리하는데 제외되도록 한다.
  4. Remark
    애플리케이션을 멈추고(STW) 최종적으로 GC 대상에서 제외될 객체(살아남을 객체)를 식별해낸다.
  5. Cleanup
    애플리케이션을 멈추고(STW) 살아있는 객체가 가장 적은 Region 에 대한 미사용 객체 제거 수행한다. 이후 STW를 끝내고, 앞선 GC 과정에서 완전히 비워진 Region 을 Freelist에 추가하여 재사용될 수 있게 한다.
  6. Copy
    GC 대상 Region이었지만 Cleanup 과정에서 완전히 비워지지 않은 Region의 살아남은 객체들을 새로운(Available/Unused) Region 에 복사하여 Compaction 작업을 수행한다.

❗️ G1GC의 마킹
SATB(Snapshot-At-The-Beginning) 알고리즘을 사용해 마킹 작업을 한다.
일시 정지가 일어난 시점 직후의 라이브 객체(스냅샷)에만 마킹을 하므로, 마킹 도중 죽은 객체도 라이브 객체로 간주된다. Remark 단계의 응답 시간이 다른 GC에 비해 더 빠른 경향이 있다.

GC Cycle

G1은 두 페이즈를 번갈아가며 GC 작업을 한다.

  • young-only : old 객체를 새로운 공간으로 옮긴다.
  • space-reclamation : 공간 회수

사이클의 흐름은 아래와 같다.

  1. old gen.의 점유율이 threshold 값을 초과 👉 Young-only Phase로 전환
  2. (Young-only Phase) Concurrent Start : 도달할 수 없는 객체들(참조되지 않는 객체)에 마킹 작업을 수행
  3. (Young-only Phase) Remark : 마킹 후 쓰레기 영역을 해제.
  4. (Young-only Phase) Cleanup : Space-Reclamation Phase로 전환해야할지 판단한다.
  5. (Space-Reclamation Phase) : young/old 영역 모두 라이브 객체를 적절한 곳으로 이동시킨다(Evacuation). 작업 효츌이 떨어지면 이 페이즈는 종료되고, 다시 Young-only 페이즈로 전환된다.

❗️ 어플리케이션 메모리가 부족한 경우 다른 GC와 마찬가지로 Full GC를 수행한다.

Mixed GC

Young/Old 영역을 모두 GC 하는 것을 의미한다. Evacaution 때 수행되는 단계와 동일하다. 즉, Evacation Pauses인데 Old Refion이 추가적으로 포함되어 있는 것이다. (Mixed GC = Evacuation Pauses(Young GC + Old GC))

기본적으로 8회 수행되도록 되어있으나 한번에 Garbage를 정리하기엔 Cost가 매우 비싸므로 1회에 모든 Old Region GC가 일어나지는 않는다.

  • Old Region에 대한 선택 기준은 라이브 객체이냐를 기준으로 한다. 즉, 효율 증대를 위해 라이브 객체는 재사용될 가능성이 높다고 판단하기 때문에 라이브 객체가 아닌 것들을 GC 하도록 한다.

minor GC와 동일하게 Eden/Survivor 영역 크기는 변경될 수 있다.

Mixed GC에 선택되는 CSet은 -XX:G1MixedGCCountTarget, -XX:G1OldCSetRegionThresholdPercent에 영향을 받는다. (Old 영역에 관한 CSet Tuning과 관련됨)

Mixed GC 선택 대상 결정은 -XX:G1MixedGCLiveThresholdPercent, -XX:G1HeapWastePercent에 영향을 받는다.

profile
🌱 😈💻 🌱

1개의 댓글

comment-user-thumbnail
2023년 12월 22일

"Old Region 에 존재하는 객체들이 참조하는 Survivor Region 을 찾는다" 이부분 설명이 잘못되지 않았을까요?

답글 달기