JVM은 크게 4개 영역으로 구성된다: 클래스 로더 시스템, 메모리, 실행 엔진, 네이티브 인터페이스.
메소드 영역 (Method Area)
MyApp.class.getSuperclass() — 메소드 영역에서 정보를 읽어옴힙 영역 (Heap)
new로 생성한 객체 인스턴스 저장App.class 객체도 힙에 생성됨OutOfMemoryError: Java heap space 발생스택 (Stack)
StackOverflowError 발생PC Register
네이티브 메소드 스택
Thread.currentThread() 같은 native 메소드가 이 스택을 사용바이트코드를 한 줄씩 읽어서 네이티브 코드로 해석하고 실행한다. 시작은 빠르지만 같은 코드를 반복 실행할 때 비효율적이다.
자주 실행되는 코드(Hot Code)를 감지해서 네이티브 코드로 미리 컴파일해둔다. 이후 해당 코드는 인터프리터를 거치지 않고 직접 실행되어 성능이 크게 향상된다.
처음 실행: 인터프리터로 실행 + 실행 횟수 카운팅
임계값 초과: JIT 컴파일 → 네이티브 코드 캐시에 저장
이후 실행: 캐시된 네이티브 코드 직접 실행
힙에서 더 이상 참조되지 않는 객체를 제거한다. GC 종류에 따라 성능 특성이 다르다.
| GC 종류 | 특징 | 적합한 상황 |
|---|---|---|
| Serial GC | 단일 스레드 처리 | 소형 애플리케이션 |
| Parallel GC | 멀티 스레드, 처리량 중심 | 배치 처리 |
| G1 GC | 힙을 Region으로 나눠 관리, STW 시간 예측 가능 | Java 9+ 기본값 |
| ZGC | STW 1ms 이하 목표 | 저지연 요구 서비스 |
Stop-The-World (STW): GC 실행 중 애플리케이션 스레드가 모두 멈추는 현상. GC 튜닝의 핵심 지표다.
OutOfMemoryError: Java heap space
→ 힙 메모리 부족. -Xmx 설정 확인, 메모리 누수 점검
OutOfMemoryError: Metaspace
→ 클래스 메타데이터 영역 부족. 클래스 로더 누수(동적 클래스 생성 과다)
StackOverflowError
→ 재귀 호출 깊이 초과. 무한 재귀 또는 재귀 깊이 설정 문제
javap -c ClassName — 바이트코드 역어셈블jmap -heap <pid> — 힙 사용량 확인jstat -gcutil <pid> — GC 통계 모니터링jstack <pid> — 스레드 덤프 (데드락 분석)