Garbage Collection : 더 이상 다른 객체에 의해 참조되지 않는 객체를 찾아 메모리를 해제하는 작업
장점
단점
참조가 끊어진 객체를 찾아내는 방법
각 객체는 자신을 참조하는 변수의 수를 나타내는 참조 카운트를 가짐
순환 참조 문제가 있음
순환 참조 문제를 해결하기 위해 고안.
STW (Stop The Wolrd) : 마킹이 이루어지는 동안 모든 애플리케이션 스레드를 중지 시켜서 그래프의 변경을 막는 작업.
JVM GC는 마크 앤 스윕 알고리즘을 기반으로 동작한다.
JVM GC는 “대부분의 객체가 생성된 직후에 참조가 끊기며, 오래 살아남는 객체는 드물다”는 세대별 가설에 기반한다. 따라서 JVM은 힙 영역을 객체의 생애 주기에 따라 두 영역으로 나누어 관리한다.
새로운 객체가 생성되면 YG의 Eden 영역에 할당된다.
Eden이 가득 차면 마이너 GC가 발생한다.
살아남은 객체들은 Survivor(0/1) 영역으로 이동하면서 Age가 1 증가한다.
마이너 GC가 반복될 때마다 두 Survivor 영역을 오가며 Age 값이 증가한다.
이때 임계값(Java 8 Parallel GC 기본값 15)에 도달한 객체는 Old Generation으로 승격(Promotion)된다.
OG영역까지 가득 차면 메이저 GC가 발생한다. 훨씬 크고 밀집된 OG 영역에서 작동하기 때문에 STW 시간이 길고, 애플리케이션 성능에 큰 영향을 미친다. 따라서 메이저 GC의 빈도와 실행시간을 줄이는 것이 GC 튜닝의 핵심 목표이다.
자바가 발전함에 따라 최적화를 위한 다양한 GC 알고리즘이 개발되었다. 이러한 알고리즘은 설정을 통해 적용할 수 있다. 즉, 상황에 따라 필요한 GC 알고리즘을 선택할 수 있다.
CPU 코어가 1개일 때 사용하기 위해 개발된 단순한 GC. 가장 STW 시간이 길다.
마이너 GC에는 복사 수거(Copy Collector), 메이저 GC에는 Mark-Sweep-Compact를 사용한다.
보통 사용하지 않는다.
java -XX:+UseSerialGC -jar Application.javaJava 8의 기본 GC
마이너/메이저 GC 작업을 멀티 스레드로 병렬 처리하여 멀티 코어에서 GC 처리량을 극대화. Java 6/7 때는 마이너 GC만 병렬 처리했는데 8 이후로는 메이저도 병렬 처리가 기본임.
java -XX:+UseParallelGC -jar Application.java
# -XX:ParallelGCThreads=N : 사용할 쓰레드의 갯수STW 시간을 최소화하는 데 초점을 맞춘 알고리즘. Mark-Sweep 작업을 애플리케이션과 동시에 수행하여 STW가 발생하는 구간을 줄임.
Compaction을 안하니까 메모리 파편화 / GC 과정 복잡함/ 높은 CPU 사용량 등의 이유로 자바 14부터 제거됨.
Java 9 이상부터 기본 GC
기존 Young/Old Generation 구분과 달리 전체 힙 영역을 여러 개의 일정한 Region으로 구분한다. 각 리전은 상황에 따라 동적으로 Eden, Survivor, Old 역할을 수행한다.
수 많은 리전 중에서 가장 많은 Garbage를 포함하는 영역을 우선적으로 수거(Garbage First)한다.
수거할 Garbage가 많을수록 GC 시간 대비 확보하는 메모리 양이 높아진다.
java -XX:+UseG1GC -jar Application.java처리량과 저지연의 밸런스를 지향한다. (균형형)
java 12에 release
G1처럼 Region 기반인데 CMS보다 더 나아가 동시 Compaction까지 수행하여 Full GC로 인한 긴 STW를 피하는 설계.
java -XX:+UseShenandoahGC -jar Application.javajava 15에 release
대량 메모리를 저지연으로 처리하기 위해 디자인된 GC
G1의 Region처럼, ZGC는 ZPage라는 영역을 사용하는데 ZPage 크기는 동적으로 운영된다.
G1에 비해 저지연을 지향, (처리량을 손해 보더라도 지연 시간 최소화)
Shenandoah와 마찬가지로 동시 Compaction을 지향하는 저지연 GC 지만, 참조 처리 방식과 내부 알고리즘이 다르다.
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar Application.java참고