티스토리 뷰
[면접 준비 - CS]Garbage Collection, G1GC, 그리고
Vagabund.Gni 2022. 12. 15. 16:32Garbage Collection
Very Short Introduction
GC는 JVM의 메모리 영역 중 메서드 영역과 힙 영역의 객체 중
더 이상 참조되지 않는 것들을 제거해 메모리를 확보하는 기법이다.
메서드 영역도 포함된다고 적긴 했지만, 클래스 로더를 직접 조작하지 않는 이상
해당 영역의 객체들은 언제나 참조되기 때문에 사실상 GC의 대상이 되지 않는다.
계속해서 GC의 통계적 배경은 무려 77년도에 처음 언급된 '약한 세대 가설'이며,
이를 한 마디로 요약하면 '오래된 객체에 비해 새로 생긴 객체의 생존율이 매우 낮다'가 된다.
조금 말을 바꾸면 '새로운 객체는 금방 참조 관계가 끊어져 버리고, 일정 이상 수명을 가진 객체의 참조 관계는 오래 유지된다'
라고 할 수 있겠다.
따라서 새로 생긴 객체와 오래된 객체의 GC 알고리즘을 다르게 구성해야 할 필요성이 생겼으며,
이를 위해 JVM의 힙 메모리 영역은 크게 Young Generation와 Old Generation을 위한 구역으로 나뉘어 구성된다.
각 구역의 알고리즘을 요약하면 아래와 같다.
- Young Generation
Young Generation Collector는 일반적으로 컬렉터를 여러 개로 복사해 작동한다.
이는 약한 세대 가설에 의해 새로운 객체는 빠르게 참조 관계가 끊어져 GC의 대상이 되는 수가 많기 때문이다. - Old Generation
Old Generation Collector는 일반적으로 컴팩트 컬렉터이다.
이는 오래된 객체일수록 메모리를 조각조각 나누어 사용하고 있을 가능성이 높기 때문인데,
컴팩트 컬렉터는 이름처럼 이런 조각을 하나로 모아 메모리 사용의 효율성을 확보한다.
How it actually works
GC의 동작 과정을 단계별로 알기 위해 위에서 물리적으로 두 개로 나눈 힙 메모리를 조금 더 세분화하자.
별 특별할 건 없고, Young Generation의 영역이 세 가지로 구분된 것을 확인할 수 있다.
이는 아마도 처리해야 할 객체의 개수가 많이 때문일 것으로 추정되는데,
새로 생긴 객체는 Eden → Survivor 0 → Survivor 1 순으로 옮겨지며 그때마다 참조되지 않는 객체는 GC 된다.
이와 같이 Young Generation 안에서 일어나는 GC를 minor GC라고 하며, 당연하게도 걸리는 시간이 짧고
STW를 발생시키지 않는다.
계속해서 Young Generation에서 오래 살아남은 객체는 Old Generation으로 이동하며,
이 영역이 가득 찰 경우 Old 영역의 모든 객체를 검사해서 메모리를 회수하는 Major GC가 실행된다.
상대적으로 시간이 오래 걸리는 작업이며, STW를 발생시켜 다른 스레드를 멈춘다.
참고로 여기서 세울 수 있는 가설은, GC의 발전은 바로 이 STW를 가능한 줄이는 방향일 것이라는 추측이며,
실제로도 그렇다.
추가로 GC의 성능 지표는 대략 아래와 같다.
- 처리량
- STW 시간
- GC 이후 메모리의 가용상태까지 걸리는 시간
또 참고의 참고로, 이 구조는 자바 8까지의 구조이며, 힙 메모리는 대략 2~4GB에서 최대 10GB까지 할당되어 사용된다.
참고의 참고의 참고로, 자바 8에서 기본으로 사용하는 GC는 멀티 스레드를 사용해 상대적으로 STW가 짧은 Parallel GC이다.
G1GC(Garbage First Garbage Collector)
G1GC의 경우, 이전처럼 힙 영역을 물리적이 아닌 논리적으로 구분한다.
따라서 각 영역의 상태에 따라 역할이 동적으로 변한다는 것을 쉽게 추측할 수 있다.
Minor, Major GC의 개념은 그대로 가져와 사용하며, 큰 객체를 위한 공간이 추가된 것을 확인할 수 있는데
멀티 프로세서와 대용량 메모리 환경을 상정해 내부 알고리즘에 변경이 있었다.
조금 구체적으로는 GC의 단계와 STW를 흩어놓고 병렬로 진행해 최소화하긴 했지만 완전히 없애지는 못했으며,
Young-Only와 Space-Reclamation의 두 페이즈를 번갈아가며 GC작업을 진행한다.
이를 간단하게 요약하면 아래와 같다.
- Initial Mark - Old Region 객체가 참조하는 Survivor Region을 검색한다(STW).
- Root Region Scan - 해당 객체들을 스캔한다.
- Old Gen의 점유율이 정해진 수치를 넘으면 Young-only 페이즈로 들어간다.
- 여기서 정해진 수치란 IHOP(InitiatingHeapOccupancyPercent)에서 정한 수치를 가리킨다.
- 더 쉽게 말하자면 Old Gen이 전체 힙 영역의 몇%를 차지할 때 시작될지를 나타내는 수치라 할 수 있다.
- Concurrent Mark - 전체 힙 영역을 스캔해 GC대상이 아닌 객체에 마킹한다.
- Remark - STW를 발생시키고 GC 대상에서 제외할 객체를 최종 식별한다.
- Cleanup - STW를 발생시키고 참조된 객체가 적은 Region부터 미사용 객체를 제거한다.
- Copy - 위의 과정에서 완전히 지워지지 않은 객체를 비어있는 영역에 모아 압축한다.
- Space-Reclamation: 모든 세대의 객체를 GC 하는 Mixed-GC로 이루어져 있다. G1이 효율이 떨어졌다고 판단하면 종료되며, 다시 Young-Only 페이즈로 돌아간다.
- 그럼 Humongous 영역은? 할당 즉시 IHOP을 확인하고 초과되었으면 즉시 강제 Young-Only 페이즈를 시작한다.
알고리즘을 살펴보면 알겠지만, 그 이름답게 G1GC는 살아있는 객체에 마킹 후
참조가 끊어진 객체가 많은 리전 먼저(Garbage First) 빠르게 회수해 메모리를 확보한다.
추가로 위에 언급했듯이 멀티 스레드를 지원하며, 수십 GB 단위의 메모리에 최적화되어 있다.
수치적으로는 힙 메모리 용량이 4GB, 객체의 사이즈가 4MB,
사용되는 객체가 약 60% 일 경우 Parallel GC에 비해서 약 세 배의 객체 처리 능력을 갖췄으며
출처: https://ionutbalosin.com/2019/12/jvm-garbage-collectors-benchmarks-report-19-12/
객체의 사이즈가 8MB이면서 GC에 최적화된 경우엔 무려 50배에 달하는 처리 능력을 보여준다고 한다.
참고로 여기서 GC에 최적화된 경우란 객체가 할당과 동시에 참조가 끊어지는 환경을 말한다.
참고의 참고로 컨테이너 구성시, CPU 코어 2개 이상, 메모리 2G 이상이 아니면 자바 버전과 상관없이 G1GC가 채택되지 않는다.
ZGC
하지만 이것도 자바 11에서의 이야기이다. 2022년 12월 기준 자바 18이 나온 시점에서 GC의 미래는 무엇일까?
답은 제목에도 적었듯이 ZGC(the Z Garbage Collector)이다.
ZGC는 테라바이트 단위의 초대용량 힙 메모리를 처리하기 위해 동시성과 확장성, 낮은 정지시간을 목표로 개발된
차세대 GC로서, 처리율이 아닌 STW의 최소화(10ms 미만) 및 대량의 메모리를 처리하기 위한 알고리즘을 목표로 하고 있다.
자바 11에도 실험적으로 도입되어 있으며, 힙 메모리 영역에서 세대 구분을 제거한 독특한 구조를 구성한다.
또한 메모리 마킹에 64bit를 활용하기 때문에, 32bit 운영체제에서는 사용할 수 없다는 특징이 있다.
알고리즘에 대해서는 일단 미뤄두고, 그래서 얼마나 빠른지 기존의 GC와 비교하면 아래와 같다.
출처: https://huisam.tistory.com/entry/jvmgc
테스트 환경은 Heap Size 128G , CPU Intel Xeon E5-2690 2.9GHz, 16core 이며,
최악의 경우 1000배에 가까운 STW 시간이 소요되는 것을 확인할 수 있다.
참고로 가비지 컬렉션 기능을 가진 언어는 Java, Python, C#, JavaScript, Ruby, Go, Swift 등이 있다.
'Development > Technical Interview' 카테고리의 다른 글
[면접 준비 - Network]양방향/단방향 암호화 (1) | 2022.12.16 |
---|---|
[면접 준비 - Network]쿠키, 세션, 토큰, 그리고 (5) | 2022.12.16 |
[면접 준비 - Network]CORS에 대하여 - 1 (1) | 2022.12.15 |
[면접 준비 - Algorithm]재귀 함수 vs. 반복문 (2) | 2022.12.14 |
[면접 준비 - Algorithm]재귀, 재귀 함수 (0) | 2022.12.14 |
[면접 준비 - Algorithm]인접 행렬, 인접 리스트 (1) | 2022.12.14 |
- Total
- Today
- Yesterday
- 지지
- 유럽여행
- 중남미
- 기술면접
- RX100M5
- 세모
- 여행
- 스프링
- 남미
- 파이썬
- Backjoon
- 동적계획법
- 유럽
- java
- 면접 준비
- 칼이사
- 알고리즘
- a6000
- 백준
- 자바
- 리스트
- BOJ
- Python
- 세계여행
- 야경
- 스트림
- spring
- 세계일주
- 맛집
- Algorithm
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |