G1GC Garbage Collector에 대해 알아보기 - 1
2023-04-02 11:27
Java 9부터 Default로 설정된 가비지 컬렉터(Garbage Collector, GC)인 G1GC에 대해 알아봅시다. 2편에서는 G1GC 의 목적과 옵션에 대한 가이드를 제공하니 프로젝트에 적용해 보세요.
개요
가비지 컬렉션(Garbage Collection)이란 말 그대로 쓰레기를 모으는 작업을 뜻한다. 자바에서 쓰레기란 사용하지 않는 객체를 뜻하며, 다음 사항에 해당하면 GC 대상이 된다.
- Local Variable Section, Operand Stack에 객체 참조정보가 없는 경우
- Method Area에 로딩된 클래스 중 Constant pool에 있는 Reference 정보가 없는 경우
- 아직 Memory에 남아 있으나 Native Method Area로 넘겨진 Object의 Reference가 JNI 형태로 참조 관계가 없는 경우
GC의 목적은 한정된 메모리 공간을 재활용하는데 있으며, 얼마나 효율적으로 이 과정을 수행하는지에 대해 Serial Collector, Parallel Collector, CMS Collector, G1 Collector와 같이 GC 알고리즘의 진화가 이루어져 왔다. 이 포스팅에서는 기초적인 GC의 내용들에 대해서 모두 다루지는 않는다. G1GC의 내용에 대해 소개한다.
용어
G1GC를 이해하는데 필요한 필수 개념을 정리한다.
용어 | 내용 |
---|---|
Evacuation | G1GC에서 일어나는 객체의 Copy 및 Moving을 뜻한다. |
Region | G1GC에서 관리하는 힙메모리 영역을 고정된 크기로 나눈 것 |
Humongous Region | 새로 할당하는 인스턴스가 리전 하나의 메모리의 반절이 넘는경우 Humongous Region이라 칭하고 G1GC에서 별도로 관리하는 영역이 된다. |
Available/Unused Region | 아무것도 할당되어있지 않은 영역, Evacuating때 이주 대상이 된다. |
CollectionSet (CSet) | GC가 수행될 Region 집합 (타겟)CSet 내 데이터는 GC 동안 모두 비워진다. (복사 혹은 이동됨)Region 집합은 Eden, Survivor, Old Generation으로 이뤄질 수 있다.CSet이 JVM에서 차지하는 비율은 1% 이내이다. |
Remembered Set (Rset) | Reference를 가진 객체가 어느 Region에 있는지 기억하기 위해 사용하는 자료구조각 Region 당 하나의 RSet이 존재하며 이를 통해 Region의 병렬 및 독립된 수집을 가능하게 한다.단일 Old generation Region을 피하기 위해 cross-region references 위치를 추적하는 것 = 한 Region에서 다른 Region을 참조한다.RSet이 차지하는 비율은 5% 이내이다. |
MixedCollection | Young/Old 영역의 GC가 일어나는것을 Mixed GC 또는 MixedCollection이라 한다. |
G1GC 소개
대용량 메모리가 있는 다중 프로세서 시스템을 대상으로 하는 서버-스타일 가비지 컬렉터
G1GC는 서버의 프로세서와 메모리의 사이즈가 커짐에 따라 개선된 GC이다. 기존의 GC가 Pause Time(Stop the world)을 극단적으로 가져가지 않기 위해 구현되었다면, G1GC는 FullGC를 최대한 피하기 위해 Pause Time을 짧게 가져가기 때문에 준 실시간 성능을 구현하였다.
- 높은 처리량과 낮은 Stop-The-World(STW) 지향
- CMS의 개선안으로 계획됨
- 쓰레기 비중이 높은 heap region을 집중적으로 수집한다.
- Java9부터 디폴트로 설정되어 있다.
-XX:+UseG1GC
옵션을 사용하여 수동으로 활성화할 수 있다.
G1은 회수 가능한 영역, 즉 쓰레기가 많을 것으로 예상되는 영역에 대한 수집 및 압축이 주가 된다. 이것이 Garbage-First, G1으로 명명된 이유이다.
Concept
Region
이전 GC와 비교했을 때, 고정된 메모리 크기로 각 Generation을 구분했던 것과 달리 힙 영역을 동일한 크기의 Region으로 나누어 관리한다.
- -XX:G1HeapResionSize : JVM 힙은 2048개의 region으로 나뉠 수 있으며, 해당 옵션을 통해 1MB ~ 32MB 사이로 지정될 수 있다.
새롭게 정의된 Humongous, Available/Unused 영역이 존재한다.
- Humongous : Region 크기의 50%를 초과하는 큰 객체를 저장하기 위한 공간. 이 Region에서는 GC가 최적으로 동작하지 않는다.
- Available/Unused : 아직 사용되지 않은 Region을 의미한다.
G1은 힙 내의 하나 이상의 Region을 단일 Region으로 객체를 복사하는데 이 때 메모리를 압축/해제 시킨다. 다중 프로세서에서 병렬 작동을 통해 STW 시간은 줄리고 처리량은 증가시킨다.
동작 방식
G1GC에서 Full GC가 수행될 때 Initial Mark ->Root Region Scan -> Concurrent Mark -> Remark -> Cleanup -> Copy 단계를 거치게 된다. 추가적으로, G1GC는 일시 정지 시간을 줄이기 위해 각 스레드가 자신만의 region을 잡고 작업하는 방식으로 병렬 GC를 수행한다.
- Initial Mark Old Region 에 존재하는 객체들이 참조하는 Survivor Region 을 찾는다. 이 과정에서는 STW 현상이 발생하게 된다.
- Root Region Scan Initial Mark 에서 찾은 Survivor Region에 대한 GC 대상 객체 스캔 작업을 진행한다.
- Concurrent Mark 전체 힙의 Region에 대해 스캔 작업을 진행하며, GC 대상 객체가 발견되지 않은 Region 은 이후 단계를 처리하는데 제외되도록 한다.
- Remark 애플리케이션을 멈추고(STW) 최종적으로 GC 대상에서 제외될 객체(살아남을 객체)를 식별해낸다.
- Cleanup 애플리케이션을 멈추고(STW) 살아있는 객체가 가장 적은 Region 에 대한 미사용 객체 제거를 수행한다. 이후 STW를 끝내고, 앞선 GC 과정에서 완전히 비워진 Region 을 Freelist에 추가하여 재사용될 수 있게 한다.
- Copy GC 대상 Region이었지만 Cleanup 과정에서 완전히 비워지지 않은 Region의 살아남은 객체들을 새로운(Available/Unused) Region 에 복사하여 Compaction 작업을 수행한다.
G1GC의 마킹
SATB(Snapshot-At-The-Beginning) 알고리즘을 사용해 마킹 작업을 한다. 일시 정지가 일어난 시점 직후의 라이브 객체(스냅샷)에만 마킹을 하므로, 마킹 도중 죽은 객체도 라이브 객체로 간주된다. Remark 단계의 응답 시간이 다른 GC에 비해 더 빠른 경향이 있다.
GC Cycle
관점에 따라 2개에서 3개의 페이즈로 구성된 “GC”로 young/old 영역의 메모리를 관리한다.
- Young-Only Phase: 일반적인 GC에서 Young영역의 Generation이 이루어지는곳 (Old 승격까지 이루어진다)
- Young-Only Phase with Initial Mark: YoungGC와 동시에 일어나는 Concurrent Marking Cycle을 수행하는 페이즈. 이 페이즈에 진입하기위해서는 특정 조건을 만족해야한다.
- Space Reclamation: Concurrent Marking Cycle이 일어난 후 Young/Old 영역의 Evacuation을 진행하는 페이즈이다. G1GC는 PauseTime을 적게 가져가기 위해 MixedCollection이 짧게 여러번 일어난다.
MixedCollection은 특정조건을 만족할 때 까지 수행한다.
- G1HeapWastePercent
The allowed unreclaimed space in the collection set candidates as a percentage. G1 stops the space-reclamation phase if the free space in the collection set candidates is lower than that.
- G1MixedGCLiveThresholdPercent
라이브 객체 점유율이 이 값보다 높은 old gen은 space-reclamation 단계에서 수집되지 않는다.
- G1MixedGCCountTarget
The expected length of the space-reclamation phase in a number of collections.
맺음말
이번 포스팅은 G1GC의 특징과 컨셉, 동작 방식에 대해 알아보고, 이해하기 위한 포스팅이었다. 이어지는 포스팅인 G1GC Option Guide를 통해 실제 G1GC를 세밀하게 컨트롤하는 방법을 알아보도록 하자.
Ref
- https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html
- https://johngrib.github.io/wiki/java-g1gc/
- https://docs.oracle.com/javase/9/gctuning/garbage-first-garbage-collector.htm#JSGCT-GUID-ED3AB6D3-FD9B-4447-9EDF-983ED2F7A573
- https://www.infoq.com/articles/G1-One-Garbage-Collector-To-Rule-Them-All/
- https://thinkground.studio/%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8-gc-%EB%82%B4%EC%9A%A9%EA%B3%BC-g1gc-garbage-first-garbage-collector-%EB%82%B4%EC%9A%A9/
- https://kwonnam.pe.kr/wiki/java/g1gc