Garbage Collection이란?
JVM의 메모리 영역 중 Heap 영역에 동적으로 할당된 메모리 중 더 이상 사용되지 않는 메모리를 찾아 제거하는 과정이다.
Heap 영역에 동적으로 할당되는 메모리들은 참조 타입의 변수의 데이터이다. Object 클래스를 상속받는 모든 아이들, 간단하게 객체라고 생각하면 된다.
Garbage Collecion 동작 과정
GC가 동작하면 메모리 영역을 스캔하며 각 객체가 Garbage Collection의 대상의 Reachable 여부를 판단한다.
여기서 Reachable이란 객체가 참조되고 있는 상태이다.
아무 곳에서도 참조하고 있지 않는 객체는 가비지 컬렉션의 대상인 Unreachable이고 스캔 이후 이러한 Unreachable 객체의 할당을 해제한다.
이후 마지막으로 메모리 재배치를 한다
그렇다면 이 과정을 언제마다 동작할까?
아래의 JVM Heap 영역과 함께 알아보자.
JVM Heap 영역
다음과 같이 크게는 Young Generation 영역과 Old Generation 영역으로 구분되고 Young Generation 영역은 Eden, Survival 0, Survival 1 영역으로 다시 구분된다.
Survival 0, 1 두 영역 중 한 곳은 항상 비어있어야 하며, 미리 적어두지만 Survival 뒤의 0, 1은 GC에서의 생존 횟수와는 무관하다.
일단 기본적으로 어느 영역이든 데이터가 다 차면 해당 영역에서 GC가 동작한다.
GC 동작마다 각 객체는 Age 값이 1씩 올라가며 특정 Age에 도달하면 Old Generation으로 넘어간다.
Young Generation에서 발생하는 GC를 Minor GC라 하고, Old Generation에서 발생하는 GC를 Major GC라 한다.
Old Generation은 Young Generation에 비해서 영역이 더 큰데 그만큼 GC에 소요되는 비용 또한 더 크다.
Young Generation
이름에서부터 알 수 있듯이, 새로 할당된지 얼마 안 된 데이터가 존재하는 영역이다.
Old Generation 영역에 비해서 메모리 영역이 작기 때문에 자주 GC가 발생하는데, 다음과 같은 이유에서이다.
자바의 객체는 대부분 일회성으로 사용되거나 금방 Unreachable 상태가 되기 때문이다.
Eden
동적 할당된 데이터가 처음 위치하는 곳이다.
Eden 영역의 메모리가 차면 GC가 진행되고 여기서 살아남은 데이터는 Survival 0/1 중 비어있지 않는 곳으로 이동된다.
Survival 0
Eden 또는 Survival 1의 GC에서 살아남은 객체들이 온다. 여기에서 메모리가 차면 GC 진행 후 Survival 1로 넘긴다.
Survival 1
Survival 0 과 동일하게 동작한다. GC 진행 후 살아남은 객체들을 Survival 0으로 넘긴다.
즉, 전체적인 흐름을 보자면 Survival 0과 1은 GC마다 살아남은 객체들을 서로서로 토스하며 Eden의 GC는 그중 데이터가 있는 쪽으로만 토스하여 항상 한쪽은 비어있는 상태를 유지한다.
Old Generation
Survival 0과 1에서 진행되는 GC로부터 특정 횟수 이상 살아남은 객체(특정 Age 이상의 객체)들이 모이는 장소이다.
Garbage Collection 튜닝
Major GC는 비용이 크다. 그렇기에 자주 발생해서는 안된다.
Major GC는 시간이 오래 걸린다. 그렇기에 Old Generation 영역을 조절하여 Major GC의 시간을 줄인다.
이 두 가지의 목적을 달성하는 것이 GC 튜닝의 목적이다.
튜닝은 가볍게만 알아두자.