가비지 컬렉터(GC)의 런타임 특성을 이해하고 분석하는 것은 여러 가지 이유로 중요합니다. 첫째, GC 일시 중지는 애플리케이션의 응답성에 직접적인 영향을 미칠 수 있습니다. 가비지 컬렉터가 어떻게 작동하는지 이해하면 설정을 최적화하여 이러한 일시 중지를 줄일 수 있습니다. 일반적으로 빈번하고 긴 GC 주기는 힙이 너무 작거나 너무 많은 임시 객체가 생성되고 있음을 나타낼 수 있습니다.
가비지 컬렉터 프로브를 활용하면 이러한 문제를 해결하고 적절한 가비지 컬렉터, 힙 크기 또는 기타 JVM 파라미터 선택과 같은 JVM 설정을 튜닝할 때 더 많은 정보에 기반한 결정을 내릴 수 있습니다.
가비지 컬렉터 프로브는 다른 프로브와 다른 뷰를 제공하며 다른 데이터 소스를 사용합니다. JVM의 프로파일링 인터페이스에서 데이터를 가져오는 대신 JFR 스트리밍을 사용하여 JDK flight recorder의 GC 관련 이벤트를 분석합니다. JFR 이벤트 스트리밍에 대한 종속성으로 인해, GC 프로브는 HotSpot JVM에서 Java 17 이상을 프로파일할 때만 사용할 수 있습니다. JFR 스냅샷을 열 때도 사용된 Java 버전과 관계없이 정확히 동일한 프로브를 사용할 수 있습니다.
Garbage collections 뷰
가비지 컬렉터 프로브의 메인 뷰는 "Garbage collections" 테이블입니다. 기록된 모든 가비지 컬렉션을 행으로 표시하고 가장 중요한 메트릭을 열로 표시합니다.
"Cause" 열은 가비지 컬렉션이 트리거된 이유를 보여줍니다. 예를 들어 System.gc() 호출은 전체 가비지 컬렉션(full garbage collection)을
트리거했습니다.
"Collector" 열의 연관된 "G1Full" 값에서 이를 확인할 수 있습니다. 또한 이로 인해 20ms의 상당한 일시 중지가 발생했는데, 이것이 일반적으로
System.gc() 호출을 권장하지 않는 이유입니다.
다른 원인들은 영 세대(young generation) 공간의 컬렉션("G1New")이나 올드 세대의 참조되지 않은 객체를 정리하는 G1 컬렉터의 혼합 GC 컬렉션("G1Old")을 트리거합니다.
영 세대 컬렉션이 더 많은 객체를 수집함에도 불구하고 혼합 GC 컬렉션이 영 세대 컬렉션보다 지속적으로 더 오래 걸리는 것을 확인할 수 있습니다.
특별한 GC 처리가 필요한 수집된 참조는 별도의 열에 "final", "weak", "soft", "phantom" 참조로 표시됩니다.
가장 긴 일시 중지와 일시 중지 합계에 대한 열이 별도로 존재하는 이유는 각 가비지 컬렉션이 개별 일시 중지를 유발하는 여러 단계(phase)로 구성되어 있기 때문입니다. 또한 가비지 컬렉션의 "Duration"은 실행되는 동안 JVM을 부분적으로만 일시 중지하기 때문에 일시 중지의 합계와 일치하지 않습니다. 스크린샷에서 "G1Old" 컬렉션은 전체 소요 시간의 약 5분의 1 동안만 일시 중지하는 것을 볼 수 있습니다.
가비지 컬렉션의 다양한 단계를 검사하려면 "GC ID" 열의 트리 아이콘을 토글할 수 있습니다.
위 스크린샷에서는 G1 컬렉터의 혼합 GC 컬렉션("G1Old")이 확장되었습니다. 대부분의 시간이 JVM을 일시 중지하지 않는 "Class Unloading"에 소요되는 것을 확인할 수 있습니다. 오른쪽에서는 가비지 컬렉션에 대한 추가 통계를 확인할 수 있습니다. 여기서는 사용된 힙은 동일하게 유지된 반면 사용된 metaspace는 0.1% 증가했습니다.
컬렉터마다 단계가 다릅니다. 위 스크린샷에는 전체 컬렉션(full collection)이 나와 있습니다. 전체 힙에서 활성 객체를 마킹하는 데 많은 시간을 소비합니다. 컬렉션이 끝났을 때 사용된 힙은 15.7% 감소한 반면 metaspace는 동일하게 유지되었습니다.
가비지 컬렉션을 분석할 때 필터링은 가비지 컬렉션의 서로 다른 하위 집합을 비교하는 중요한 도구입니다. 테이블 상단에는 원하는 열을 선택하고 해당 필터를 구성할 수 있는 필터 선택기가 있습니다. 유사한 가비지 컬렉션을 확인하는 더 쉬운 방법은 테이블의 컨텍스트 메뉴를 사용하여 선택한 행의 열 값을 기반으로 필터 조건을 선택하는 것입니다.
관심 있는 가비지 컬렉션을 좁혀보기 위해 여러 필터를 추가할 수 있습니다. 활성 필터는 테이블 상단에 레이블로 표시됩니다. 중첩된 GC 단계 테이블에서 필터를 추가할 수도 있습니다.
텔레메트리
GC 프로브는 여러 텔레메트리를 생성하며, 이는 "Telemetries" 프로브 뷰에서 확인할 수 있습니다.
GC 일시 중지를 최소화하는 데 관심이 있다면 상단의 "Longest pause" 텔레메트리가 가장 유용할 것입니다. 텔레메트리의 시간 축을 따라 드래그하여 "Garbage Collections" 뷰에서 해당하는 가비지 컬렉션을 선택할 수 있습니다. 수직 해상도를 높이려면 상단의 드롭다운에서 단일 텔레메트리를 선택하거나 텔레메트리 이름을 클릭하면 됩니다.
위 스크린샷에서는 시간에 따른 일시 중지 합계를 확인할 수 있습니다. JProfiler는 기록된 데이터의 히스토그램을 구축하여 합산 가능한 측정값을 표시합니다. 빈(bin) 너비는 사용 가능한 가로 공간에 따라 달라지므로, 히스토그램 빈은 줌 레벨과 ("scale to fit"이 활성화된 경우) 창 너비에 따라 변경됩니다. 변하지 않는 것은 모든 히스토그램 빈 아래의 총 면적입니다.
힙 및 metaspace 텔레메트리는 가비지 컬렉션을 확장할 때 볼 수 있는 통계를 기반으로 합니다. 이는 전체 프로파일링 세션의 메모리 텔레메트리처럼 데이터가 정기적으로 샘플링되지 않음을 의미합니다. 특정 기간 동안 가비지 컬렉션이 발생하지 않으면 데이터가 존재하지 않습니다. 할당 활동이 거의 없는 JVM의 경우, 시간 축을 따라 두 가비지 컬렉션 사이에서 그래프가 단순히 보간되는 긴 구간이 있을 수 있습니다.
이러한 각 텔레메트리에는 "Before GC"와 "After GC"라는 두 개의 데이터 라인이 있습니다. "Used Heap" 텔레메트리의 경우 일반적으로 그 차이가 큽니다. 각 시점에서 두 데이터 라인의 값을 비교하여 가비지 컬렉션이 수행한 작업량을 확인할 수 있습니다. 정확한 값을 확인하려면 툴팁을 참조하십시오. "Committed heap" 텔레메트리와 metaspace 텔레메트리의 경우 두 라인 간의 차이가 작은 경우가 많습니다.
JFR 스냅샷을 분석하는 경우, jdk.GCHeapSummary JFR 이벤트 유형의 동일한 데이터가
텔레메트리 섹션의 "Memory" 텔레메트리에서도 사용됩니다.
그러나 이 경우 "Before GC" 및 "After GC" 값이 모두 동일한 데이터 라인에 표시되며 GC 프로브 텔레메트리에서처럼 데이터가 초당 1회 단위로 집계되지 않으므로 그래프가 다르게
표시됩니다.
GC 요약
GC 요약은 전체 기록 기간 동안 집계된 측정값을 보여줍니다. 각 측정값은 가비지 컬렉션 횟수뿐만 아니라 평균, 최대값 및 합계 값을 제공합니다. 상단의 가장 중요한 데이터는 애플리케이션의 활성도에 직접적인 영향을 미치는 "Pause times"입니다.
다른 최상위 카테고리는 모든 컬렉션의 총 시간을 보여주며, 이는 다시 영 및 올드 컬렉션을 위한 두 개의 하위 카테고리로 나뉩니다.
GC 구성
가비지 컬렉터를 튜닝할 때 명시적으로 설정할 수 있거나 가비지 컬렉터 자체에 의해 암묵적으로 설정되는 공통 속성을 검사하고자 할 수 있습니다.
이러한 속성은 모든 가비지 컬렉터에 공통적이며 가비지 컬렉터 간의 차이점을 이해하는 데 도움이 됩니다.
GC 플래그
마지막으로 GC 관련 플래그는 가비지 컬렉터의 어떤 속성을 튜닝할 수 있는지에 대한 아이디어를 제공하며 실제 값을 확인할 수 있도록 해줍니다.
"Origin" 열은 플래그가 어떻게 설정되었는지를 보여줍니다. "Default" 값은 기본 설정에서 수정되지 않은 것이며, "Ergonomic" 플래그는 가비지 컬렉터에 의해 자동으로 조정된 것입니다. 명령줄에서 특정 GC 플래그를 설정한 경우 오리진(origin)에 "Command line"으로 보고됩니다.



















