
1. JVM이란?
JVM(Java Virtual Machine)은 자바 애플리케이션을 실행하기 위한 가상 머신이다. 자바로 작성된 코드는 .java → .class 파일로 컴파일되고, 이 바이트코드를 JVM이 해석하거나 컴파일하여 실행한다.
JVM은 운영체제 위에서 동작하며, 자바 프로그램이 플랫폼에 독립적으로 실행될 수 있도록 해주는 핵심 요소다.
2. JVM의 주요 구성 요소
JVM은 크게 실행 엔진과 메모리 영역으로 나뉘며, 각 구성 요소는 다음과 같은 역할을 수행한다.
2.1 Class Loader Subsystem
- 클래스 파일을 메모리로 로드하고, 검증 및 초기화 과정을 수행한다.
2.2 Runtime Data Area (메모리 영역)
- JVM이 애플리케이션을 실행하는 동안 사용하는 메모리 공간이다.
| 영역 | 설명 |
| Heap | new로 생성된 객체와 배열이 저장되는 공간. GC의 주요 대상 |
| Stack | 각 스레드마다 생성되며, 메서드 호출 시의 지역 변수와 프레임 정보 저장 |
| Method Area | 클래스 정보, static 변수, 상수 풀 등이 저장 |
| PC Register | 현재 실행 중인 명령어 주소 저장 |
| Native Method Stack | 네이티브 코드 실행 시 사용되는 스택 |
2.3 Execution Engine
- 바이트코드를 기계어로 변환하여 실행
- JIT(Just-In-Time) 컴파일러가 성능 최적화를 위해 사용됨
3. JVM Heap 구조
Heap 영역은 Young Generation과 Old Generation으로 나뉜다.
- Young Generation: 새로 생성된 객체가 저장된다. 이 영역에서 발생하는 GC는 Minor GC라고 한다.
- Old Generation: Young 영역에서 일정 시간 이상 살아남은 객체들이 이동하는 공간이다. 이 영역에 대한 GC는 Major GC라고 한다.
- Metaspace: 클래스 메타데이터가 저장되는 공간. JDK 8 이후 PermGen을 대체함.
4. Garbage Collection(GC) 방식
GC는 사용되지 않는 객체를 메모리에서 제거해주는 자동 메모리 관리 기능이다. GC 방식은 다음과 같이 구분된다.
4.1 Serial GC
- 단일 스레드로 GC를 수행
- 구조가 단순하고 작은 애플리케이션에 적합
- -XX:+UseSerialGC
4.2 Parallel GC
- 여러 스레드를 사용해 GC를 병렬로 수행
- Throughput(전체 처리량)을 중시하는 시스템에 적합
- -XX:+UseParallelGC
4.3 CMS GC (Concurrent Mark Sweep)
- Stop-the-world 시간을 최소화하기 위해 GC 작업을 병렬로 나누어 수행
- 단점으로는 메모리 단편화 문제가 존재
- -XX:+UseConcMarkSweepGC (JDK 9 이후 deprecated)
4.4 G1 GC (Garbage First)
- 힙을 작은 Region 단위로 나누고, GC Pause를 예측 가능하게 조절
- 최근 JVM의 기본 GC 방식으로 사용되는 경우가 많음
- -XX:+UseG1GC
4.5 ZGC / Shenandoah
- 지연 시간을 매우 짧게 유지할 수 있도록 설계된 최신 GC 방식
- 수백 GB 이상의 대용량 힙을 효율적으로 처리
- -XX:+UseZGC, -XX:+UseShenandoahGC
5. GC가 중요한 이유
GC의 동작 방식은 애플리케이션의 성능, 응답 속도, 안정성에 직접적인 영향을 준다. GC가 자주 발생하거나 정리 시간이 길어지면 다음과 같은 문제가 발생할 수 있다.
- 애플리케이션 응답 지연 (GC pause)
- OutOfMemoryError 발생
- 시스템의 CPU 사용률 상승 및 처리량 감소
따라서, 시스템의 특성과 목적에 맞는 GC 방식을 선택하고 적절히 튜닝하는 것이 매우 중요하다.
6. GC 방식 선택 가이드
| 환경 | 적합한 GC |
| 단순 구조, 리소스 적음 | Serial GC |
| 높은 처리량 필요 | Parallel GC |
| 멈춤 시간 최소화 | CMS, G1 GC |
| 대규모 서비스, TB 단위 Heap | ZGC, Shenandoah |
7. JVM은 기본적으로 GC를 선택한다
- JVM은 Java 버전에 따라 기본으로 사용하는 GC 방식이 다르다.
- 예를 들어, Java 8에서는 Parallel GC가 기본이고,
- Java 9 이상에서는 G1 GC가 기본이다.
- 특별히 명시하지 않으면 JVM이 알아서 적절하다고 판단하는 GC를 사용하게 된다.
8. 원하는 GC를 명시적으로 설정할 수 있다
JVM 실행 옵션을 통해 GC 방식을 직접 설정할 수 있다. 예를 들어:
java -XX:+UseG1GC -jar myapp.jar
| GC 종류 | 설정 옵션 |
| Serial GC | -XX:+UseSerialGC |
| Parallel GC | -XX:+UseParallelGC |
| CMS GC (JDK 8까지) | -XX:+UseConcMarkSweepGC |
| G1 GC | -XX:+UseG1GC |
| ZGC (JDK 11+) | -XX:+UseZGC |
| Shenandoah (JDK 12+/RedHat 기반) | -XX:+UseShenandoahGC |
주의: JVM 버전마다 지원하는 GC가 다르므로, 선택하기 전에 현재 사용하는 Java 버전이 해당 GC를 지원하는지 확인해야 한다.
9. GC 선택은 단순히 "바꾸면 끝"은 아니다
GC를 변경하면 다음과 같은 영향이 있다:
- Pause 시간이 달라짐
- CPU 사용량이 달라짐
- 메모리 사용 패턴이 달라짐
- 기존 설정들 (-Xmx, -Xms, -XX:SurvivorRatio 등)도 GC에 따라 다르게 작용할 수 있음
따라서, 단순히 -XX:+UseZGC와 같은 옵션만 추가하는 것보다는,
어떤 GC가 어떤 특징을 가지고 있는지 이해하고,
시스템의 요구 사항 (지연시간 vs 처리량 등) 에 맞춰 선택하는 것이 중요하다.
10. 어떤 GC를 선택해야 할지 모를 때는?
- 지연 시간에 민감한 애플리케이션 (예: 게임, 실시간 거래 시스템) → G1 GC, ZGC, Shenandoah
- 배치 처리, 서버 리소스를 최대 활용하는 시스템 → Parallel GC
- 리소스 제한이 있는 임베디드 환경 → Serial GC
- 아직은 크게 상관 없고, 기본값이면 충분한 경우 → JVM 기본 설정 유지 (대부분 G1 GC)
11. 내 애플리케이션이 현재 어떤 GC를 쓰는지는 어떻게 알 수 있나?
GC 로그를 확인하거나, 실행 시 다음과 같은 옵션으로 JVM 설정을 출력해볼 수 있습니다:
java -XX:+PrintCommandLineFlags -version
출력 결과에 UseG1GC, UseParallelGC 등 어떤 GC가 활성화되어 있는지 확인할 수 있다.
'Programming > Java' 카테고리의 다른 글
| OutOfMemoryError 발생 상황과 해결 방법 (2) | 2025.04.18 |
|---|---|
| 면접에서 진짜 자주 나오는 자바 질문 - 섹션 7. JVM, GC, 자바 런타임 메커니즘 (1) | 2025.04.17 |
| JAVA 자주 나오는 자바 면접 질문 30개 예시 (0) | 2025.04.17 |
| 면접에서 진짜 자주 나오는 자바 질문 - 섹션 6. 스프링 MVC & REST API 설계 (0) | 2025.04.17 |
| 면접에서 진짜 자주 나오는 자바 질문 - 섹션 5. 예외 처리, 로깅, 설계 패턴 (0) | 2025.04.17 |