# G1 GC 동작 원리: 핵심 요소를 통한 깊이있는 이해
자바 성능 튜닝을 위해 가장 중요한 요소 중 하나는 가비지 컬렉션(GC)이다. 그중에서도 본 포스팅에서는 최신 버전의 JDK에서 기본으로 설정되는 G1(Garbage-First) GC에 대해 깊이 있게 알아볼 것이다.
1. G1 GC란?
G1 GC는 '가비지 먼저'라는 이름에서 알 수 있듯이, 메모리에서 가비지가 가장 많이 발생한 영역부터 청소를 시작하는 가비지 컬렉터이다. 이전의 CMS(Concurrent Mark Sweep) GC와 달리, G1 GC는 메모리를 작은 영역들로 나누고, 가비지가 많이 쌓인 영역부터 우선적으로 청소한다.
2. G1 GC의 동작 방식
G1 GC의 동작은 크게 네 가지 단계로 이루어진다.
- **초기 표시(Initial Mark)**: 이 단계에서는 GC Root에서 시작해서 객체를 추적하며, '살아있는' 객체를 표시한다. 이 단계는 STW(Stop The World) 단계로, 모든 애플리케이션이 중단된다.
- **병렬 표시(Concurrent Mark)**: 초기 표시 단계에서 표시된 객체로부터 참조되는 다른 객체들을 표시한다. 이 작업은 애플리케이션의 동작과 병행해서 수행된다.
- **재표시(Remark)**: 참조가 변경된 객체를 다시 추적하고 표시한다. 이 단계 역시 STW 단계로, 애플리케이션이 일시 중지된다.
- **청소(Cleanup)**: 마지막으로, 쓸모 없는 객체(가비지)를 제거하고, 메모리를 재구성한다.
3. G1 GC의 장점과 단점
장점
- **예측 가능한 퍼포먼스**: G1 GC는 일정한 퍼포먼스를 제공한다. 최대 GC 정지 시간을 설정할 수 있기 때문에, 원하는 성능 목표를 유지하는 데 도움이 된다.
- **대용량 힙에 대한 지원**: G1 GC는 대용량 힙을 가진 애플리케이션에 이상적이다. 다른 GC 알고리즘에 비해 더욱 효율적으로 메모리를 관리할 수 있다.
단점
- **프로세서 오버헤드**: G1 GC는 복잡한 알고리즘을 사용하기 때문에, 프로세서 사용량이 증가할 수 있다. 이는 CPU에 대한 부하를 늘릴 수 있으므로 주의해야 한다.
- **이해와 튜닝의 복잡성**: G1 GC의 튜닝은 그 자체로 복잡하다. 다양한 옵션과 매개변수를 이해하고 조정하는 데는 시간과 경험이 필요하다.
4. G1 GC Full GC 동작 과정
1. **초기 표시(Initial Mark)**
애플리케이션의 실행을 일시 중단하고, GC Root로부터 시작하여 각 객체가 살아있는지 아닌지를 추적하고 표시하는 작업을 수행합니다. 이는 다른 모든 애플리케이션 스레드가 정지된 STW(Stop-The-World) 단계이며, 이 단계에서는 '살아있는' 객체를 표시하는 초기 표시 작업이 수행됩니다.
2. **병렬 표시(Concurrent Mark)**
이 단계에서는 초기 표시 단계에서 표시된 살아있는 객체로부터 참조되는 다른 객체들을 추적하며 표시하는 작업이 병행으로 수행됩니다. 이 단계는 애플리케이션의 동작과 동시에 실행되므로 애플리케이션의 실행을 크게 방해하지 않습니다.
3. **재표시(Remark)**
애플리케이션의 실행을 다시 중단하고, 병렬 표시 단계 동안 참조가 변경된 객체를 다시 추적하고 표시하는 작업을 수행합니다. 이 단계 역시 STW 단계입니다.
4. **청소(Cleanup)**
이 단계에서는 '살아있지 않은' 객체를 제거하고, 메모리를 재구성하는 작업이 수행됩니다. 이 단계에서는 빈 영역을 식별하고 회수합니다.
5. **복사(Compaction)**
쓰레기 수집 후, 메모리가 부족하거나 분산되어 있을 경우에, 사용중인 객체를 새로운 영역으로 복사하여 메모리를 압축합니다. 이 과정은 메모리 할당을 보다 효율적으로 만듭니다.
G1 GC의 동작 과정은 이러한 순서대로 진행되며, 메모리를 효율적으로 관리하도록 설계되어 있습니다. 그러나 각 단계는 복잡하고 세밀한 튜닝이 필요하므로, 애플리케이션의 성능을 최적화하기 위해서는 이에 대한 깊은 이해가 필요합니다.
5. G1 GC의 전체 동작 과정
분할된 영역 (Regions): G1 GC는 힙을 여러 개의 동일한 크기의 영역으로 분할합니다. 이러한 영역은 "Old", "Eden", "Survivor", 또는 "Humongous" 등의 타입으로 분류됩니다.
- 분할된 영역 (Regions): G1 GC는 힙을 여러 개의 동일한 크기의 영역으로 분할합니다. 이러한 영역은 "Old", "Eden", "Survivor", 또는 "Humongous" 등의 타입으로 분류됩니다.
- Young Generation의 수집 (Minor GC): Young 영역은 Eden과 Survivor 영역으로 나뉘며, 새로 생성된 객체를 저장합니다. Minor GC는 Young Generation에서 발생하며, 다음 단계로 수행됩니다.
- Eden 영역에 객체가 가득 차면, Minor GC가 발생합니다.
- 살아남은 객체는 Survivor 영역으로 이동됩니다.
- 여러 번 살아남은 객체는 Old 영역으로 프로모션됩니다.
- Mixed GC의 수행: G1은 더 긴 시간 동안 살아남은 객체를 수집하기 위해 Old 영역에서의 GC를 수행할 수 있습니다.
- Mixed GC는 Young 영역과 함께 가장 쓰레기가 많은 Old 영역을 수집합니다.
- G1은 여기서 멈추지 않고 다음 Mixed GC를 계획하여 Old 영역의 다른 부분을 점차 수집합니다.
- Humongous Allocation 및 수집: Humongous 영역은 특정 크기보다 큰 객체를 위한 것입니다. 이러한 객체는 Humongous Allocation으로 할당되며, 특별한 수집 과정을 거칩니다.
- 중단 시간 (Pause) 최적화: G1은 일시 중단 시간을 짧게 유지하려고 노력합니다. 이를 위해 병렬 처리와 효율적인 작업 분배를 활용합니다.
- 기타 최적화: G1 GC는 런타임 동안 가비지 컬렉션의 성능을 모니터링하고, 가능한 한 더 효율적인 수집을 위해 내부적으로 최적화를 수행합니다.
마무리
G1 GC는 현대 멀티코어, 대용량 메모리 시스템에 최적화된 GC이다. 하지만, 그 복잡성 때문에 튜닝에는 많은 노력이 필요하다. 이 포스팅을 통해 G1 GC의 동작 원리에 대한 더 깊은 이해를 하셨기를 바랍니다.
'Java' 카테고리의 다른 글
synchronize 라는 키워드를 함수에 사용하면 어떻게 동작해야 하나요? (1) | 2023.12.27 |
---|---|
자바 버전별 주요 기능: Java 8, 11, 17의 혁신 (1) | 2023.12.08 |
자바의 가비지 컬렉션: 이해하기 쉽게 보는 동작 과정 (0) | 2023.06.05 |
싱글톤 패턴(Singleton Pattern): 그것이 무엇인가? (0) | 2023.05.28 |
추상 클래스와 인터페이스: 이해와 차이점 (0) | 2023.05.27 |