Oracle의 공식문서 HotSpot Virtual Machine Garbage Collection Tuning Guide을 참고했습니다.
📍 세대별 가비지 컬렉션 (Generational Garbage Collection)
📍 세대 (Generations)
📍 성능 고려 사항 (Performance Considerations)
📍 처리량(Throughput) 및 메모리 사용량(Footprint) 측정
Java SE 플랫폼의 강점 중 하나는 메모리 할당과 가비지 컬렉션의 복잡성을 개발자로부터 숨겨준다는 점이다.
그러나 가비지 컬렉션이 주요한 병목 현상이 될 경우, 구현 방식의 일부를 이해하는 것이 유용하다. 가비지 컬렉터는 애플리케이션이 객체를 사용하는 방식에 대한 가정을 바탕으로 동작하며, 이러한 가정은 조정 가능한 매개변수(튜닝 가능한 파라미터)로 반영된다. 이를 조정함으로써 추상화의 장점을 유지하면서도 성능을 개선할 수 있다.
객체는 실행 중인 프로그램에서 다른 살아있는 객체의 어떤 참조(reference)에서도 접근할 수 없을 때 가비지(garbage)로 간주되며, VM은 이 객체의 메모리를 재사용할 수 있다.
이론적으로 가장 직관적인 가비지 컬렉션 알고리즘은 매번 실행될 때마다 모든 접근 가능한 객체를 반복적으로 확인하는 것이다. 남겨진 객체들은 가비지로 처리된다. 그러나 이 방식은 실행 시간의 복잡도가 살아있는 객체 수에 비례하기 때문에, 많은 데이터를 유지하는 대규모 애플리케이션에서는 비효율적이다.
Java HotSpot VM은 여러 가비지 컬렉션 알고리즘을 포함하고 있으며, 세대별 가비지 컬렉션(Generational Collection) 기법을 사용한다.
순진한(naive) 가비지 컬렉션은 매번 모든 살아있는 객체를 검사하지만, 세대별 가비지 컬렉션은 애플리케이션에서 객체가 사용되는 특정 패턴을 활용하여 불필요한 작업을 최소화한다.
이러한 패턴 중 가장 중요한 것은 “약한 세대 가설(Weak Generational Hypothesis)” 이다.
이는 대부분의 객체는 생성된 후 아주 짧은 시간 내에 사용이 끝난다는 점을 의미한다.

그림은 객체의 수명 분포를 보여준다.
그래프의 왼쪽에 있는 가파른 피크(peak) 는 대부분의 객체가 생성 직후 곧바로 소멸됨을 의미한다.
예를 들어, 반복자(iterator) 객체는 보통 하나의 루프 동안만 살아 있다가 제거된다.
반면, 일부 객체는 오래 살아남아 그래프의 오른쪽으로 분포가 늘어진다.
예를 들어, 초기화 시점에 생성된 객체는 JVM이 종료될 때까지 유지될 수 있다.
이 두 극단 사이에는 중간 정도의 계산(computation)이 지속되는 동안만 유지되는 객체들이 존재하며, 그래프에서 초기 피크 이후의 작은 봉우리가 이에 해당한다.
일부 애플리케이션은 다른 분포를 보일 수 있지만, 대부분의 애플리케이션에서는 이와 비슷한 형태를 가진다.
결과적으로, 대부분의 객체는 금방 소멸한다는 점을 이용하면 효율적인 가비지 컬렉션이 가능하다.
가비지 컬렉션을 최적화하기 위해 JVM은 객체의 수명에 따라 메모리를 세대(Generation) 단위로 관리한다.
각 세대는 일정 크기의 메모리 풀(pool)이며, 각 세대가 가득 차면 해당 세대에서 가비지 컬렉션이 수행된다.

가비지 컬렉션의 주요 성능 지표는 처리량(Throughput)과 지연시간(Latency) 이다.
트레이드오프 (Trade-off)
가비지 컬렉션 성능을 분석하기 위해 JVM 로그를 활용할 수 있다.
-verbose:gc
-Xlog:gc*
출력 예시
[10.191s][info][gc] GC(36) Pause Young (G1 Evacuation Pause) 391M->114M(508M) 13.075ms