[Java] GC Implementations - 가비지 컬렉션 구현
😎 서론
이전 글을 통해 JVM 내에서 GC가 어떻게 동작하는지를 학습하였다.
하지만, GC도 여러 종류로 구현을 한 것을 알게 되었고, 그 부분에 대해서 다뤄보려 한다.
이전글 - [Java] GC (Garbage Collection) ??
😁 본론
JVM에서 GC 구현은 5가지의 유형이 존재합니다.
- Serial Garbage Collector
- Parallel Garbage Collector
- CMS Garbage Collector
- G1 Garbage Collector
- Z Garbage Collector
하나씩 알아보겠습니다.
Serial Garbage Collector
특징
- Mark-Sweep-Compact 알고리즘을 사용합니다.
- GC가 싱글 스레드로 동작합니다.
- 싱글 스레드이기에 다른 멀티로 동작하는 GC에 비해 stop-the-world 시간이 깁니다.
- 싱글 스레드이기에 서버 환경과 같은 다중 스레드 응용 프로그램에서 사용하는 것은 부적절 합니다.
- 일시 중지 시간 요구 사항이 적고, 클라이언트 스타일 시스템에서 실행되는 대부분 응용 프로그램에서 선택하는 GC입니다.
사용법
java -XX:+UseSerialGC -jar Application.java
Parallel Garbage Collector
특징
- Mark-Sweep-Compact 알고리즘을 사용합니다.
- GC가 멀티 스레드로 동작합니다.
- 멀시 스레드이기에 Serial GC에 비해 stop-the-world 시간이 줄어듭니다.
- 최대 GC 스레드 수, 일시 중지 시간, 처리량 및 사용 공간(Heap Size)을 지정할 수 있습니다.
사용법
java -XX:+UseParallelGC -jar Application.java
CMS Garbage Collector
특징
- Mark-Sweep 알고리즘을 사용합니다. (Compact 과정이 빠졌습니다!)
- Serial GC 와 Parallel GC 의 긴 Full GC 주기를 줄이기 위해서 고안되었습니다.
- GC가 싱글 스레드로 동작하며, 다른 GC들과 같이 진행됩니다.
- 애플리케이션이 실행되는 동안 GC와 프로세서 리소스를 공유하기 위해 설계되었습니다.
- 이 GC를 사용하는 애플리케이션은 평균적으로 느리게 응답하지만 가비지 수집을 수행하기 위해 응답을 멈추지 않습니다.
- Java 9 부터 더이상 사용되지 않습니다. 만약 사용하려고 하면, 경고 메세지가 출력됩니다.
>> java -XX:+UseConcMarkSweepGC --version
Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated
in version 9.0 and will likely be removed in a future release.
java version "9.0.1"
- Java 14 부터는 완전히 중단되었습니다.
>> java -XX:+UseConcMarkSweepGC --version
OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC;
support was removed in 14.0
openjdk 14 2020-03-17
동작순서
Initial Mark : 클래스 로더와 가장 가까운 살아있는 객체를 찾습니다.
Concurrent Mark : 방금 살아있다고 확인한 객체가 참조하는 객체를 따라가며 확인합니다.
Remark : Concurrent Mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인합니다.
Concurrent Sweep : GC 대상을 정리합니다.
장점
- 애플리케이션 스레드와 동시에 백그라운드 GC 스레드가 돌아가기 때문에 stop-the-world 시간이 매우 짧습니다.
단점
- 다른 GC 방식보다 메모리와 CPU를 많이 사용합니다.
- 백그라운드 GC 스레드는 압축을 하지 않으므로 힙이 단편화될 수 있습니다.
- 단편화가 많이 일어나 Compaction 작업이 실행되면 다른 GC 방식보다 stop-the-world 시간이 더 길어지는 상황도 발생합니다.
사용법
java -XX:+UseParNewGC -jar Application.java
G1(Garbage First) Garbage Collector
특징
- Mark And Sweep And Compact 알고리즘을 사용합니다.
- Garbage만 있는 Region을 먼저 회수한다고 해서 붙여진 이름입니다.
- CMS GC를 개선한 GC로서 CMS를 대체하고 있습니다.
- Java 7 이후부터 사용할 수 있습니다.
- 대용량의 메모리(4GB 이상)가 있는 멀티 프로세서 시스템을 위해 제작되었습니다.
- 기존 Heap 영역과는 다르게 일정한 크기의 Region으로 나누었습니다.
- 전체 Heap이 아닌 Region 단위로 탐색을 진행합니다.
기존 Heap 영역과는 조금 다른 모습으로 표현되고 있습니다.
그 중에서도 Humonogous와 Available / Unused 처럼 못 봤던 region이 표현되어 있습니다.
Humonogous : Region 크기의 50%를 초과하는 큰 객체를 저장하기 위한 공간
Available / Unused : 아직 사용되지 않는 Region
동작순서
Initial Mark
- (STW 발생) Old Region 에 존재하는 객체들이 참조하는 Survivor Region을 찾습니다.
Root Region Scan
- 위에서 찾은 Survivor 객체들에 대해 스캔 작업을 실시합니다.
Concurrent Mark
- 전체 Heap의 Scan 작업을 실시하고, GC 대상 객체가 발견되지 않은 Region은 이후 단계를 제외합니다.
- Region 영역 내에 모든 객체가 GC 대상인 Region 영역을 표시해둡니다.
Remark
- (STW 발생) 최종적으로 GC 대상에서 제외할 객체를 식별합니다.
- Concurrent Mark 단계에서 표시해둔 모든 GC 대상의 Region을 바로 회수합니다.
Cleanup
- (STW 발생) 살아있는 객체가 가장 적은 Region에 대한 미사용 객체를 제거합니다.
Copy
- 살아남은 객체들을 새로운 Region(Available / Unused) Region에 복사하여 Compaction을 수행합니다.
사용법
java -XX:+UseG1GC -jar Application.java
Z Garbage Collector
특징
- Linux용 실험 옵션으로 Java 11에서 등장하였습니다.
- JDK 14는 Windows 및 macOS 운영체제에서 ZGC를 도입했습니다.
- ZGC는 Java 15부터 프로덕션 상태를 얻었습니다.
- 10ms 이상 애플리케이션 스레드의 실행을 중단하지 않고, 비용이 많이 드는 모든 작업을 동시에 수행 하므로 낮은 대기 시간이 필요한 애플리케이션에 적합합니다.
- 스레드가 실행 중일 때 동시 작업을 수행하기 위해 컬러 포인터가 있는 로드 장벽을 사용하고 힙 사용량을 추적하는 데 사용됩니다.
- 참조 색상(색상 포인터)은 ZGC의 핵심 개념입니다.
- 이는 ZGC가 참조의 일부 비트(메타데이터 비트)를 사용하여 객체의 상태를 표시한다는 것을 의미합니다.
- 8MB에서 15TB 크기의 힙을 처리할 수 있습니다.
- 일시 중지 시간은 힙, 라이브 세트 또는 루트 세트 크기에 따라 증가하지 않습니다.
사용법
JDK 15미만에서 활성화
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC Application.java
JDK 15 이상
java -XX:+UseZGC Application.java
버전 별 Default GC는?
Java 5 ~ 8
- Server Class Machine : Parallel Garbage Collector
- Client Class Machine : Serial Garbage Collector
Java 9 ~ 17
- Server Class Machine : G1 Garbage Collector
- Client Class Machine : Serial Garbage Collector
Server Class Machine 으로 정의하는 기준
- 2개 이상의 CPU
- 2GB 이상의 Memory
현재 기준(2022-03-13)
Java 17 LTS까지 나왔기 때문에 17버전까지 기록해두었습니다.
😀 결론
Z GC는 아직까지는 보편화가 되지 않았기 때문에 자세히까지 알 필요는 없을 것 같지만,
자바 11부터는 많이 쓰고 있는 현재 기준으로는
G1 GC에 대해서는 어떻게 동작하는지 알고 있는 게 좋을 것 같았다.
참고자료
https://maruoov.tistory.com/6
https://www.baeldung.com/jvm-garbage-collectors
https://syhwang.tistory.com/89
https://stackoverflow.com/questions/33206313/default-garbage-collector-for-java-8
https://www.javamadesoeasy.com/2016/12/what-is-default-garbage-collector-for.html
https://www.oracle.com/java/technologies/javase/gc-tuning-6.html
https://docs.oracle.com/javase/1.5.0/docs/guide/vm/gc-ergonomics.html
https://stackoverflow.com/questions/70664562/criteria-for-default-garbage-collector-hotspot-jvm-11-17
https://github.com/openjdk/jdk/blob/3121898c33fa3cc5a049977f8677105a84c3e50c/src/hotspot/share/runtime/os.cpp#L1673
https://huisam.tistory.com/entry/jvmgc