이번 장에서는 자신의 프로젝트의 GC 종류를 변경하면서 벤치마크를 진행해보고 서비스에 가장 적합한 GC를 선택해본다.
Jmeter, nmon, nmonchart, Pinpoint가 익숙하지 않다면 [Pinpoint] 개념 (링크), [부하 테스트] Jmeter 설정 (링크), [부하 테스트] 서버 설정 (링크) 글을 확인하고 오길바란다.
GC 목록
- Serial GC
- Parallel GC
- Parallel Old GC (Parallel Compacting GC)
- CMS (Concurrent Mark & Sweep GC)
- G1GC (Garbage First)
- ZGC
참고
- EazyGC 사이트를 통해 로그를 분석하는 방법과 VisualVM을 통한 Heap & Thread Dump를 분석하는 방법과 nmonchart, pinpoint의 경우 추후에 따로 다루도록 한다.
- Serial GC의 경우 서버에서는 사용하면 안되고 저사양 클라이언트 프로그램에만 사용해야하는 GC이지만 서버에서 사용할 경우 얼마나 성능이 나빠지는지 확인하기 위해 목록에 추가하였다.
- ZGC의 경우 최근에 나온 GC로써 경우에 따라 기존에 가장 성능이 좋았던 G1GC보다 우월하게 성능이 좋다는 벤치마크 결과가 있어서 추가하였다.
단, 우리의 서비스는 JDK 8 환경에서 작동하는데 G1GC의 경우 Java 9부터 Default가 되었고 ZGC의 경우 Java 11에 추가되었다. G1GC와 ZGC의 경우 Java 11 환경에서 테스트를 진행한다. - 벤치마크를 진행하고 문서들을 참고하면서 간략하게 JVM 이란?과 Heap & GC에 대한 정보를 정리해두었다.
- 벤치마크를 진행하면서 문서들을 참고하여 GC 종류별 작동 방식을 정리해두었다. ZGC의 경우 작동원리가 명확히 파악되지 않아서 관련된 이미지 파일과 링크를 첨부해두었다.
- 벤치마크의 형평성을 위하여 설정 (JAVA_OPTS)에 GC를 선택하는 부분을 제외한 GC 성능 관련 옵션을 사용하지 않았으며 자동으로 JVM에서 설정하도록 두었다.
툴
- VisualVM: Thread Dump 분석 (Heap Dump 분석도 가능하지만 아래의 MAT 분석이 더 많은 기능을 제공한다.)
- MAT: Heap Dump 분석
- Nmon: 서버 Resource 모니터링
- Pinpoint: Application 모니터링
- Jmeter: 클라이언트 Application & 요청 결과 통계 추출
- EasyGC: GC로그를 통한 분석 사이트
Application 설정
설정 (JAVA_OPTS)방법은 Serial GC, Parallel GC, Parallel Old GC, CMS GC (이하 A GCs)와 G1GC, ZGC (이하 B GCs)가 다르다. 두 설정 모두 다루도록 한다.
- Heap & Thread Dump를 위한 설정
- A GCs
# 이전 생략
# GC가 수행될 때 Heap 상세 정보를 출력
-XX:+PrintHeapAtGC
# OOM이 발생하였을 경우 Heap Memory Dump
-XX:+HeapDumpOnOutOfMemoryError
# Full GC 이전에 Heap Memory Dump
-XX:+HeapDumpAfterFullGC
# Full GC 이후에 Heap Memory Dump
-XX:+HeapDumpBeforeFullGC
# Heap Memory Dump 파일 저장 경로
-XX:HeapDumpPath=/home/heap-dump
# 이후 생략
- B GCs (A GCs와 중복되는 부분 생략)
# 이전 생략
# A GCs의 PrintHeapAtGC와 동일
-Xlog:gc+heap=trace
# 이후 생략
- Thread Dump 분석
Dump 추출 방법은 A GCs와 B GCs가 달랐지만 분석 방법은 동일하다. (예시는 G1GC의 Dump 파일로 진행)
- VisualVM을 실행시킨다.
- 생성된 Dump 파일을 Drag & Drop 한다.
- 아래의 이미지와 같은 화면이 나온다면 정상적으로 분석이 완료된 것이다.
- Heap Dump 분석
- MAT를 실행시키고 Dump 파일을 선택한다.
- 아래의 이미지와 같은 화면이 나온다면 정상적으로 분석이 완료된 것이다.
- GC Log 추출을 위한 설정
- A GCs
# 이전 생략
# GC가 수행될 때 로그를 생성
-verbose:gc
# GC가 수행될 때 더 제사한 정보를 출력
-XX:+PrintGCDetails
# JVM이 시작된 시간을 기준으로 GC가 발생한 시간을 출력
-XX:+PrintGCTimeStamps
# 실제 시간을 기준으로 GC가 발생한 시간을 출력
-XX:+PrintGCDateStamps
# GC가 수행될 때 Application이 중단된 시간을 출력
-XX:+PrintGCApplicationStoppedTime
# 인스턴스의 참조정보를 출력
-XX:+PrintReferenceGC
# System.gc()를 통한 Full GC 무효화
-XX:+DisableExplicitGC
# GC Log 저장 경로
-Xloggc:/home/gc-log
# 사용하려는 GC 종류를 선택
-XX:+UseSerialGC
or -XX:+UseParallelGC
or -XX:+UseParallelOldGC
or -XX:+UseConcMarkSweepGC
# 이후 생략
- B GCs (A GCs와 중복되는 부분 생략)
# 이전 생략
# A GCs의 verbose:gc와 동일한 역할
-Xlog:gc*
# A GCs의 PrintGCApplicationStoppedTime과 동일
-Xlog:safepoint
# 이후 생략
- GC Log 분석 방법
Log 추출 방법은 A GCs와 B GCs가 달랐지만 분석 방법은 동일하다. (예시는 G1GC의 Log 파일로 진행)
ZGC의 경우 GCEasy 사이트에서 정상적으로 분석이 되지 않았다. Log의 형태를 확인해보았을 때 다른 GC Log의 파일과 상당부분 형식이 달랐는데 출시된지 오래되지 않은 GC라서 아직 GCEasy 사이트에서 지원하지 않는 것으로 예상된다.)
- GCEasy (링크)사이트로 접속한다.
- GC Log 파일을 Drag & Drop 하고 Analyze 버튼을 클릭한다.
- 아래의 이미지와 같은 화면이 나온다면 정상적으로 분석이 된 것이다.
지금까지 Heap & Thread Dump 파일과 GC Log파일을 만들고 각 툴에서 분석 결과를 추출하는 방법에 대해서 알아보았다. [JVM] GC 벤치마크 분석 포인트 (링크) 에서는 추출한 결과를 분석하는 방법에 대해서 알아본다.
'Java > JVM' 카테고리의 다른 글
[JVM] GC 벤치마크 결과 (0) | 2022.01.23 |
---|---|
[JVM] GC 벤치마크 분석 포인트 (0) | 2022.01.23 |
[JVM] GC 알고리즘 종류 (0) | 2021.12.02 |
[JVM] Heap & GC (0) | 2021.12.02 |
[JVM] JVM 이란? (0) | 2021.12.02 |