최근 Java 8에서 Java 21로 업그레이드하면서 JVM 내부 구조나 GC 동작 방식에 많은 변화가 있었다.
버전 업그레이드를 진행하면서 단순히 버전 숫자만 올라간 것이 아니라, 메모리 관리 방식, GC 동작 원리, 그리고 이에 따른 서비스 성능에도 다양한 영향을 미치게 되었다.
이번 글에서는 Java 8과 Java 21을 기준으로 GC와 JVM 메모리 구조의 변화, 그리고 이러한 변화가 실무에 어떤 영향을 주는지 정리해본다.
Java 8 vs Java 21 핵심 변화 정리
항목 Java 8 Java 21 변화 포인트
| 기본 GC | Parallel GC | G1 GC | 안정성 중심으로 변경 |
| 추가 GC | 없음 | ZGC, Shenandoah | 초저지연 GC 등장 |
| PermGen 영역 | 존재 | 삭제, Metaspace로 통합 | OutOfMemory 리스크 개선 |
| GC Log | PrintGCDetails | Xlog:gc* | 더 체계적 & 가독성 향상 |
JVM 메모리 구조와 GC 동작 방식
Java Heap은 크게 Young Generation과 Old Generation으로 나뉜다. Young Generation 내부에는 Eden 영역과 두 개의 Survivor 영역(S1, S2)이 존재하며, 객체의 생명주기와 GC 동작에 따라 객체가 각 영역을 이동하게 된다.
Heap Memory
├── Young Generation
│ ├── Eden Space
│ └── Survivor Space (S1 / S2)
└── Old Generation
영역별 역할
영역 역할 주요 동작
| Eden | 새 객체 생성 공간 | Minor GC 발생 시 정리 |
| Survivor (S1, S2) | Eden에서 살아남은 객체 임시 공간 | 나이(Age) 쌓여서 Old 이동 준비 |
| Old | 장수 객체 공간 | 주기적으로 Major / Full GC 발생 |
객체 이동 흐름
- Eden 영역에서 객체 생성
- Minor GC 발생 시 살아남은 객체가 Survivor 영역으로 이동
- Survivor 영역에서 Age가 증가
- 특정 Age 이상이 되면 Old 영역으로 Promotion
- Old 영역이 가득 차면 Major GC 또는 Full GC 발생
대부분의 객체는 Eden에서 바로 사라지며, 실제 Old 영역까지 생존하는 객체는 많지 않다.
GC 성능 최적화 시 기대할 수 있는 효과
개선 항목 기대 효과
| GC Pause Time 감소 | API 응답속도 개선 |
| Old Promotion 최적화 | TPS 안정화 |
| Full GC 빈도 감소 | 서비스 장애 리스크 감소 |
| 메모리 효율 증가 | CPU 리소스 절감 |
특히 WebFlux나 Reactive 구조의 서비스에서는 GC Pause Time이 늘어날 경우 시스템 전체 지연 시간 증가로 이어질 수 있기 때문에 GC 튜닝은 매우 중요한 요소가 된다.
Java 21 권장 GC 설정 및 옵션
Web API 또는 WebFlux 기반 서비스 기준으로 G1 GC를 기본으로 사용하는 것이 권장된다.
G1 GC 옵션 예시
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+ParallelRefProcEnabled
-XX:+UnlockExperimentalVMOptions
-XX:G1NewSizePercent=30
-XX:G1MaxNewSizePercent=60
만약 초저지연(ultra low-latency) 서비스라면 ZGC 사용을 고려할 수 있다.
-XX:+UseZGC
GC 로그 설정 (Java 21)
GC 로그 분석을 위한 설정도 필수적으로 고려하는 것이 좋다.
-Xlog:gc*,gc+heap=debug,gc+pause=debug:file=gc.log:time,uptime,level,tags
메모리 사용량 비교 및 분석을 위한 툴 추천
GC 동작뿐만 아니라 Heap 메모리 사용량을 비교하거나 객체 수를 분석할 때 다음과 같은 툴들을 활용할 수 있다.
툴 주요 특징
| VisualVM | 가볍고 직관적인 모니터링 및 HeapDump 분석 |
| Eclipse MAT | 대용량 HeapDump 분석에 최적화 |
| JProfiler | 유료 프로파일러, 실시간 분석 및 Heap 분석 지원 |
HeapDump 분석을 통해 클래스별 메모리 사용량, Old Generation 사용량, 주요 객체 Top N 등의 정보를 비교 분석할 수 있다.
참고하면 좋은 공식 자료
- Java 21 GC 공식 문서 : https://openjdk.org/jeps/140
- VisualVM : https://visualvm.github.io/
- Eclipse MAT : https://www.eclipse.org/mat/
- ZGC 소개 : https://wiki.openjdk.org/display/zgc/Main
결론 및 정리
Java 8에서 Java 21로 업그레이드하면서 JVM과 GC 구조는 단순한 버전업 이상의 변화를 가져왔다. GC 방식과 메모리 관리 방식이 개선되면서 서비스 성능, 응답속도, 안정성에 큰 영향을 미치게 된다.
업그레이드 이후에는 GC 옵션 튜닝, HeapDump 분석, GC 로그 설정 등을 통해 시스템을 최적화하고 문제를 미리 방지하는 것이 매우 중요하다.
HeapDump 분석 툴을 활용하면 메모리 사용 패턴을 더 명확히 파악할 수 있고, GC 로그 분석을 통해 성능 개선 포인트를 쉽게 찾을 수 있다.
'java' 카테고리의 다른 글
| Java 예외 처리 방식: Exception 클래스를 개별 생성 vs Enum으로 관리 (1) | 2024.12.20 |
|---|---|
| 인터페이스 VS 추상 클래스 (0) | 2024.12.18 |
| Java11 (0) | 2023.12.07 |
| Java8 (1) | 2023.12.07 |
| Java8 VS Java11 (0) | 2023.12.07 |