JAVA | G1 GC

송은석·2022년 11월 21일
0

들어가기 전, CMS GC와의 간단 비교

CMS GC

  • 애플리케이션 스레드와 함께 GC가 동작할 수 있으므로 비교적 적은 STW(Stop the World)가 발생한다.
  • Compaction을 하지 않고, Free List를 사용하여 적절한 공간에 객체를 카피하거나 프로모션한다. 이는 객체들로 하여금 Eden, Survivor 영역에 오래 머무르도록 한다는 단점이 있으나, Compaction이 워낙 고비용이므로 Promotion이 빈번하지 않다면 성능상 더 나을 수도 있다.

G1 GC

  • Heap 영역을 이전의 Young - Old gerenation의 물리적 구조가 아닌 region이라는 논리적 구조로 재구성했다. 따라서 작은 gc 수행 단위를 통해 더 적은 suspend time으로 STW를 수행할 수 있게 되었다.
  • Compation(기존 generation 모델과는 조금 다르지만)을 수행함으로써 CMS 모델에서 있었던 파편화를 피할 수 있게 되었다.


G1 GC

  • G1 GC는 수행 시 먼저 Heap 영역 전체에서 Garbage의 비율이 높은 Region을 파악하여 해당 region을 우선적으로 처리한다. 이에 Garbage First GC라는 이름을 가지게 되었다.
  • G1은 사용자가 지정된 목표 시간 내에 가능한 많은 Heap 영역을 가장 합리적으로 GC하고자 한다. 하나 이상의 region에서 하나의 region 개체로 live object들이 복사되며, 다중 스레드에 의해 구출된다.
  • 따라서 G1 GC는 Heap 크기가 크고(6GB 이상), 0.5초 미만의 안정적이고 예측 가능한 일시 중지 시간을 원할 때 사용하기에 적합하다.


G1 GC CYCLE

  • G1 GC Cycle은 크게 Young-only, 그리고 Space Reclamation으로 나뉜다.

  • Young-only 단계는 Old generation(Old+Humongous) 가 정해진 threshold를 초과했을 경우 시작된다. 먼저 Concurrent Start를 통해 도달할 수 있는 객체에 마킹 작업을 하고, Remark 시에 마킹을 끝내고 Young generation에서의 Garbage를 회수한다. 그리고 Cleanup 단계에 Space Reclamation 단계로 넘어갈 지를 결정한다.
    위 그림에서 파란색 영역에서는 STW와 함께 minor gc가 발생한다. 주황색 영역에서는 Mixed Gc로 minor gc와 major gc가 함께 발생하는데, Old gen 영역은 마킹만 할 뿐 회수하지는 않는다.

  • Space Reclamation 단계는 Young-only 단계에서 마킹한 region의 메모리를 회수하는 단계로, 이 때 Mixed Collection이 수행되며 마킹 단계가 없으므로 STW의 빈도가 줄어들게 된다.

    Young/Old gen 모두의 Live 객체를 적절한 곳에 대피(Evacuation)시킨다.

    Space Reclamation이 종료될 경우 다시 Young only 단계로 돌아간다.


Remember Set

하나의 region 마다 하나씩 주어지는 영역으로, 주어진 영역의 외부 참조를 추적하고 기록하는 곳이다. 전체 Heap 공간의 5% 미만을 차지하며, 이를 통해 region의 병렬적이고 독립적인 GC가 가능하게 된다.

Collection Set

GC에서 수집될 영역의 집합으로, 이 영역의 기록된 모든 영역은 GC 중 비워지게 된다. 전체 Heap 공간의 1% 미만을 차지하며, eden, survivor, old gen이 기록될 수 있다.

Humongous Object

  • Humongous Object란 한 region 크기의 절반 이상 크기를 지닌 객체를 의미한다.
  • 이 객체는 연속된 region을 순차적으로 차지하도록 할당된다. 마지막 region에 잉여 공간이 남아도 사용하지 않는다.
  • 이 객체 할당 시 G1은 IHOP을 확인하고 IHOP이 초과된 상태라면 강제로 (force) Young Collection을 실시한다.
  • 큰 객체는 Full Gc에도 옮겨지지 않으며, 이로 인해 Fragmentation이 발생할 수 있으며, Full GC가 느려질 수 있다.


IHOP(Initiating Heap Occupancy Percent)

  • G1 GC의 마킹 발동 기준이 되는 값으로, Old generation의 사이즈에 대한 백분율이다.


SATB 알고리즘

  • G1 GC는 SATB 알고리즘을 사용하여 객체를 마킹(Marking)한다.
  • SATB는 일시정지(STW)가 일어난 직후의 Live Object만을 마킹하며, 따라서 마킹 도중 죽은 객체도 라이브 객체로 간주하는 보수적인 특징이 있다.

Evacaution Failure(대피 실패)

  • 애플리케이션이 너무 많은 메모리를 쓰고 있어서, 객체 대피 시 복사시킬만한 공간이 충분치 않으면 대피 실패가 발생한다.
  • 이미 이동시킨 객체는 새 위치를 유지하고, 아직 이동하지 않은 객체는 복사하지 않는다.
  • 최대한 상태를 유지한 채로 GC를 종료하고, 만약 GC가 정상 종료되지 않을 경우 Full GC가 예약된다.



참고

웹 사이트 | https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html
웹 사이트 | https://docs.oracle.com/en/java/javase/12/gctuning/garbage-first-garbage-collector.html#GUID-E9CB81BC-92E5-489E-8A2E-760691A41CDF
웹 사이트 | https://johngrib.github.io/wiki/java-g1gc/
웹 사이트 | https://jypthemiracle.medium.com/weekly-java-트래픽이-많이-몰리는-이벤트가-예정되어-있을-때-young-gen과-old-gen의-비율-고민하기-3adfeca388af
웹 사이트 | https://javabom.tistory.com/7
profile
Done is better than perfect🔥

0개의 댓글