Garbage Collector
사용하지 않는 메모리를 프로그래머가 직접 관리 하지 않아도 자동적으로 동적으로 할당된 메모리 영역 중 사용하지 않는 영역을 탐지하여 해제하는 기능
Heap vs. Stack - 동적/정적으로 할당된 메모리 영역
Garbage Collection 과정
Mark and Sweep
•
Garbage collector가 stack의 모든 변수를 스캔한다. 각각 어떤 객체를 참조하고 있는지 찾아서 마킹하고, 마킹되지 않은 객체를 heap에서 제거한다
Garbage Collection이 일어나는 시기
Heap은 New Generation과 Young Generation으로 나누어져 있고, New Generation은 Eden, Survival 0과 survival 1으로 나누어져 있다
1.
Eden은 새로운 객체에게 항당되는 영역.이 영역이 꽉 차게 되면 garbage collection이 발생한다.
New Generation에서 활동하는 gc를 minor garbage collector 라고 한다
2.
Eden 영역에서 reachable 상태를 유지하여 살아남은 객체는 survival 0로 옮겨진다.
3.
다시 eden에 새로운 객체가 할당되고, 꽉 차면 garbage collection을 발생시키고, reachable한 객체가 survival 0으로 옮겨지는 과정이 반복된다.
4.
survival 0이 다 차면 garbage collection이 이루어지고, survival 1의 메모리 영역이 사용된다. 그리고 eden에서 살아남은 객체는 survival 1로 옮겨지게함으로써 survival 0과 1중 한 영역만 사용한다.
5.
survival 1이 차면 garbage collection이 이루어지고, survival 0으로 옮겨진다. 이렇게 surival 0과 1을 번갈아 가며 옮겨질 때마다 이동한 객체는 age값이 증가하게 되고, 특정 age값을 넘어가게 되면 old generation으로 옮겨지는 데 이것을 promotion 이라고 한다.
6.
앞의 과정들이 반복되면 old generation이 차게 되고, 그러면 garbage collection이 실행된다 (major garbage collector).
Garabe Collector의 종류
•
Serial GC
•
Parallel GC
•
CMS GC
•
C1 GC
Serial GC
•
GC을 처리하는 스레드가 1개 이다
•
CPU 코어가 1개만 있을 때 사용하는 방식
•
Mark-Compact collection알고리즘을 사용
◦
데이터가 삭제되고 난후 군데 군데 남은 데이터들을 한곳에 몰아서 저장함으로써 메모리 파편화를 방지
Parallel GC
•
GC를 처리하는 스레드가 여러개이다
•
SERIAL GC보다 빠르게 객체를 처리할 수 있다
•
메모리가 충분하고 코어의 개수가 많을 때 사용하면 좋다
Concurrent Mark Sweep GC (CMS GC)
Stop The World 시간을 최소화하기 위해 만들어 졌다
Stop-The-World
GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것
gc를 실행하는 스레드를 제외한 나머지 스레드는 모두 작업을 멈추었다가 gc가 작업을 완료한 후에 다시 재개한다.
Unreachable 한 객체를 한번에 찾지 않고 나눠서 찾는 방식을 사용
•
Initial Mark: 클래스 로더에서 가장 가까운 객체 중 살아 있는 객체만 찾는다
•
Concurrent Mark: 위에서 살아 있다고 확인한 객체에서 참조되어 있는 객체를 확인한다
•
Remark: 위 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인한다
•
Concurrent Sweep: 쓰레기를 정리한다
Serial GC
나의 스레드로 GC를 실행하다 보니 Stop The World 시간이 길다
CMS GC
Paralell GC
여러 개의 스레드로 GC를 실행하므로 앞선 Serial GC보다 Stop The World 시간이 짧아
•
Stop The World 시간을 최소화하기 위해 만들어 졌지만 다른 GC에 비해 사이클이 길어 CPU가 더 많이 사용되고 Mark And Sweep 과정 이후 메모리 파편화를 해결하는 Compaction이 기본적으로 제공되지 않는다
•
이 때문에 시스템이 장기적으로 운영되다가 조각난 메모리들이 많아 Compaction 단계를 수동으로 수행하면 오히려 Stop The World 시간이 길어지는 것을 알 수 있다.
•
Java 14 버전부터는 사용이 중단되었다.
C1 GC
•
Heap을 일정 크기의 Region으로 잘게 나누어 어떤 영역은 Young Generation, 어떤 영역은 Old Generation으로 사용
•
GC가 일어날 때 전체 영역 (Eden, survival, old generation)을 탐색하지 않고 꽉 차 있는 region만 탐색
•
런타임에 따라 필요에 따라 영역 별 Region 개수를 튜닝함으로써 Stop The World를 최소화할 수 있다
•
Java 9이상부터는 G1 GC를 기본 GC 실행 방식으로 사용한다.