# 4회차 - (2025.07.29 / G1GC Marking)

## 1. G1GC Marking 을 강조하여 시점을 설명

### Minor GC (모든 과정은 STW)&#x20;

* GC 루트부터 마킹을 시작해서 관련한 도달 가능한 객체를 타고 들어가면서 모두 마킹
* RSet(Old -> Young) 을 확인해서 만약 해당하는 객체가 있다면 마킹&#x20;
* 마킹이 마무리 되고 마킹이 되지 않은 객체들을 대상으로 CSet 에 추가&#x20;
* CSet 에 추가된 리전들을 대상으로 copy & compact 과정 진행&#x20;
  * CSet 에 추가할 때는 기본적으로 목표 STW 에 가장 유리한 리전들을 포함시킨다.&#x20;

### Major GC&#x20;

* Concurrent Marking Cycle
  * Initial Mark (STW)&#x20;
    * IHOP 임계값이 45% 가 넘어간다면 GC 루트부터 마킹을 시작&#x20;
      * Minor GC 가 마무리된 시점에는 Young 영역에 객체가 할 수 있는 만큼은 정리가 완료된 상태&#x20;
      * 때문에, Minor GC 가 마무리 된 시점에 Initial Mark 를 진행하는 것을 매우 효율적
    * RSet(Young -> Old) 을 확인해서 만약 해당하는 객체가 있다면 마킹&#x20;
  * Concurrent Mark (Concurrent)&#x20;
    * initial Mark 과정에서 마킹된 객체를 시작으로 도달 가능한(reachable) 모든 살아있는 객체들을 찾아서 마킹한다.&#x20;
    * 이 과정은 애플리케이션 스레드와 Concurrnet 하게 발생하기 때문에, 참조가 변경될 가능성이 있다.&#x20;
    * 때문에, SATB(Snapshop-At-The-Beginning) 알고리즘을 사용해 마킹 시작 시점의 힙 스냅샷을 기준으로 살아있는 객체를 판단한다. 만약 Concurrent Mark 단계 중 애플리케이션 스레드에 의해서 객체 참조가 변경된 케이스가 있다면 **SATB 버퍼에 변경 이전 참조값(3색 알고리즘 : G1GC 때 처음 도입된 개념)을 저장한다.**&#x20;
      * **SATB 버퍼에 변경 이전 참조값을 넣어두어야만 애플리케이션 스레드가 하나의 참조를 계속 변경하더라도 이전 참조값만 보면 Remark 단계에서 간결하게 마지막에 변경된 참조를 확인할 수 있다.**&#x20;
    * 또한, TAMS(Top-At-Mark-Start) 포인터를 사용하여 해당 포인터 이후에 생성된 객체는 다음 사이클에 처리하도록 한다.&#x20;
  * Remark (STW)
    * Concurrent Mark 단계에서 Write Barrier 를 통해 SATB 버퍼에 기록된 참조 변경 정보들을 확인해 최종적으로 마킹을 확정짓는다.&#x20;
  * Cleanup (STW)
    * 완전히 비어있는 영역을 Free List 에 추가한다.&#x20;
    * 살아있는 객체 비율을 분석하고, 이 비율을 기반으로 CSet 을 구성한다.&#x20;
* Mixed GC (STW)&#x20;
  * Mixed GC는 Young Generation과 더불어, 효율성이 높은 일부 Old Generation 리전들을 CSet에 포함하여 수집한다.&#x20;
  * Minor GC(Young GC)가 어차피 STW를 유발하기 때문에, 이 STW 시간 동안 Old 영역의 일부도 함께 처리하여 GC 효율을 극대화하고 전체적인 STW 횟수를 줄이는 효과가 있다. "한 번의 정지 시간에 두 가지 일을 처리한다"고 볼 수 있다.
