본문 바로가기
Backend/Java

Serial GC / Parallel GC / G1 GC

by DooDuZ 2024. 6. 19.

Serial GC

가장 단순한 가비지 컬렉터로 하나의 스레드를 사용하여 GC를 수행한다. 여기서 말하는 스레드는 CPU의 물리적인 처리 단위를 의미 한다. GC 발생 시 Stop The World가 발생하며 사용하는 스레드가 적은 만큼 그 시간도 길다. Minor GC에선 Mark(unreachable 인스턴스 마킹)과 Sweep(메모리 해제)이, Old GC에선 Compact(메모리 단편화 해소)까지 진행된다.

 

Parallel GC

Serial GC가 싱글 스레드를 사용했다면, Parallel GC는 Minor GC에서 멀티 스레드를 사용하여 GC를 수행한다. 스레드가 늘어나는 만큼 Serial GC에 비해 상대적으로 Stop The World 시간이 짧다. Serial GC와 마찬가지로 Mark - Sweep - Compact의 순서로 진행된다. Old Generation까지 멀티 스레드로 동작하는 Parallel Old GC도 있다.

 

G1 GC

eden, survivor, old generation을 물리적으로 나눠 사용하던 위의 GC들과 다르게 각 영역을 동일한 크기의 Region이라는 단위로 나누어 사용한다. 각 영역의 역할은 동적으로 할당된다.

 

필자는 아무리 봐도 어떻게 효율적으로 작동하는지 이해가 안돼서... 다만 공식 문서의 몇 부분만 번역기 돌리기 + 예전 GC강의 자료 일부를 합쳐서 남겨둔다. 응애 개발자를 벗어나면 이해할 날도 오겠지...

https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html

 

Getting Started with the G1 Garbage Collector

Java Overview Java is a programming language and computing platform first released by Sun Microsystems in 1995. It is the underlying technology that powers Java programs including utilities, games, and business applications. Java runs on more than 850 mill

www.oracle.com

 

Heap Structure

힙은 하나의 메모리 영역이 여러 개의 고정된 크기의 영역으로 분할된다. Region은 1~32Mb 크기로 약 2000개로 나누어진다. Region은 eden, survivor, old generation으로 할당된다. 살아남은 인스턴스는 한 영역에서 다른 영역으로 이동된다. Region은 다른 애플리케이션 스레드를 모두 중지시키지 않고 병렬로 수집될 수 있도록 설계되었다.

 

G1에서의 Young GC

살아 있는 객체들은 하나 이상의 survivor 영역으로 이동한다. 객체의 age가 임계값에 도달하면 old generation으로 승격된다. 이 과정은 Stop The World가 발생한다.

 

G1 수집 단계 정의

Initial Mark(STW) : Young GC 발생 시 함께 진행된다. old generation에 있는 객체들을 참조하는 survivor 영역(루트 영역)을 마킹한다. 일반적인 Minor GC에 비해 빠르다.

 

Root Region Scanning : survivor 영역에서 old generation으로의 참조를 스캔한다. 이 과정은 애플리케이션이 실행되는 동안 계속해서 발생한다. young GC가 발생하기 전에 반드시 이 단계가 완료되어야 한다.

 

Concurrent Marking : 전체 힙에서 라이브 인스턴스를 찾는다. 앱이 실행되는 동안 Initial Marking된 객체들을 그래프를 통해 추적한다.

 

Remark (STW) : 라이브 인스턴스의 의 마킹을 완료한다. CMS 컬렉터(STW를 줄이기 위한 GC 알고리즘, 현재는 사용 중지)에서 사용된 것보다 훨씬 빠른 SATB(Snapshot-at-the-beginning) 알고리즘을 사용한다.

 

Cleanup (STW and Concurrent) : 완전히 비어 있는 영역을 해제하고 기억 집합(Remembered Sets)을 정리한다. (Stop the world) 비어 있는 영역을 초기화하고 자유 리스트로 반환한다. (Concurrent)

더보기

👉 기억 집합(Remembered Sets) - 출처 GPT...!! 신뢰성 높지 않음!

 

가비지 컬렉션에서 빠른 접근을 위해 사용되는 데이터 구조입니다. 일반적으로 복잡한 객체 그래프에서 참조 관계를 추적하고, 이러한 참조 관계가 업데이트될 때 어떤 객체가 더 이상 사용되지 않는지 판단하는 데 도움을 줍니다.

Copying (STW) : 라이브 인스턴스의 마킹은 Young GC 작업과 결합하여 수행되며 로그에 GC pause(young)(initialmark)
라고 표기된다. 또는 Young과 Old Generation 영역 모두에서 수행될 수 있으며, 이는 GC Pause (mixed) 으로 기록된다.

 

GC 순서

1. Initial Mark

Young GC에서 라이브 오브젝트의 초기 마킹이 진행된다. 로그에서는 이를 GC pause(young)(initialmark)로 기록한다.

2. Concurrent Marking

`X`라고 표기된 빈 Region이 발견되면 Remark 단계에서 즉서 제거되며 활성을 결정하는 어카운팅 정보가 계산된다.

 

3. Remark

빈 영역이 제거되고 회수되며 모든 영역에 대해 라이브네스가 계산된다.

 

4. Copying/Cleanup

G1은 "생존성(liveness)"이 가장 낮은 영역을 선택하는데 이는 가장 빠르게 수집할 수 있는 영역들이다. 이 지역은 Young GC와 동시에 수집되며 로그에 GC pause (mixed)로 표기된다. Young, Old 제너레이션이 동시에 수집된다.

 

5. After Copying / Cleanup

선택 영역이 그림과 같이 압축된다.

'Backend > Java' 카테고리의 다른 글

Virtual Thread  (0) 2024.08.05
JVM Stack / Heap - GC  (0) 2024.06.19
Java Compile  (2) 2024.06.07