Java 애플리케이션이 실행될 때, JVM은 프로그램을 구동하기 위해 Runtime Data Area(실행 시 데이터 영역)을 생성한다.
이 영역은 다음과 같이 구성된다.
Runtime Data Area = Method Area + Heap Area + Thread Private (Stack Area + PC Register + Native Method Stack × N)
📍 Thread Private 영역
Stack Area, PC Register, Native Method Stack은 스레드마다 독립적으로 존재한다.
즉, 멀티 스레드 환경에서는 각 스레드가 자신의 스택과 레지스터를 따로 갖고 실행된다.
Stack Area
- 메서드 호출 시마다 프레임이 쌓이며, 재귀 호출이 계속 반복되어 스택이 한계치에 다다르면 StackOverflowError가 발생한다.
- 지역 변수, 매개변수, 연산 중간 결과 등이 저장된다.
☕ JVM Virtual Memory 구조
JVM은 결국 하나의 프로세스(Process)다.
따라서 프로세스가 사용하는 가상 메모리 공간(Virtual Memory Space) 내에서 동작한다.
32비트 프로세스 기준으로는 총 2³²바이트, 즉 4GB의 가상 메모리가 주어진다.
이 중 일반적으로 다음과 같이 나뉜다:
| 구분 | 용량 | 설명 |
| 사용자 애플리케이션 영역 | 약 2GB | JVM이 실제 사용할 수 있는 영역 |
| OS 커널 영역 | 약 2GB | 운영체제 전용 |
→ 하지만 실제로는 OS가 내부적으로 사용하는 공간이 더 있기 때문에 JVM이 실질적으로 활용 가능한 메모리는 약 1.7GB 정도로 제한된다.
💡 서버 환경에서는 이 메모리 제약이 훨씬 더 중요해진다.
클라이언트 앱은 상대적으로 여유롭지만, 서버 프로세스는 다수의 스레드와 객체를 동시에 관리하기 때문이다.
💾 Heap Area (힙 영역)
- JVM 메모리 중 가장 큰 영역으로 모든 객체 인스턴스와 배열이 생성되는 공간이다.
- GC(Garbage Collector)가 관리하는 대상이다.
- JVM 실행 시 -Xms, -Xmx 옵션으로 초기 및 최대 크기를 조정할 수 있다.
하지만 힙을 무조건 크게 잡는다고 좋은 것은 아니다.
힙이 커질수록 GC가 스캔해야 할 영역이 넓어져 전체적인 성능이 떨어질 수 있다.
✅ 적절한 힙 크기는 애플리케이션의 객체 생성 패턴과 GC 방식을 고려해 설정해야 한다.
🧩 Method Area (메소드 영역)
- JVM이 읽어 들인 클래스, 인터페이스, 메서드, 필드 정보가 저장되는 공간이다.
- JIT 컴파일러가 변환한 기계어 코드 캐싱 공간으로도 사용된다.
- Java 8부터는 PermGen이 제거되고 Metaspace가 도입되었다.
💡 PermGen → Metaspace 변화
| 구분 | PermGen (Java 7 이하) | Metaspace (Java 8 이상) |
| 위치 | JVM Heap 내부 | Native Memory (OS 영역) |
| 크기 | 고정적 | 동적 확장 가능 |
| 문제점 | 크기 제한으로 OOM(OutOfMemory) 발생 | OS 메모리를 활용하여 유연함 |
즉, 운영 중 피크 부하나 대규모 클래스 로딩 상황에도 Metaspace는 자동으로 크기가 확장되어 대응 가능하다.
🔗 Runtime Constant Pool (런타임 상수 풀)
클래스 로딩 시, JVM은 클래스 파일에 포함된 다음 정보를 Runtime Constant Pool에 저장한다:
- 클래스 버전, 필드, 메서드, 인터페이스 정보
- 각종 리터럴(literal)
- 심볼 참조(symbolic reference)
예를 들어,
A.a() 내부에서 B.b()를 호출
이 경우 "B.b()"라는 문자열 형태의 심볼 참조가 상수 풀에 저장된다.
이후 JVM이 클래스 로딩 및 링크 과정을 거치며 실제 메모리 주소로 바인딩되는 과정을 해석(Resolution)이라고 한다.
📘 런타임 중에도 새로운 상수가 추가될 수 있으며, 이 영역은 동적으로 관리된다.
전체 요약
| 구분 | 주요내용 | 관리방식 |
| Method Area | 클래스 메타정보, static 변수, JIT 코드 | Metaspace (Native 메모리) |
| Heap Area | 인스턴스 객체, 배열 | GC 관리 |
| Stack Area | 메서드 호출 프레임, 지역 변수 | Thread별 독립 |
| PC Register | 현재 실행 중인 명령어 주소 | Thread별 독립 |
| Native Method Stack | JNI 관련 네이티브 코드 실행 | Thread별 독립 |
| Runtime Constant Pool | 리터럴, 심볼 참조, 클래스 메타데이터 | 동적 관리 |
정리
- JVM은 하나의 프로세스로서 OS의 Virtual Memory Space 안에서 동작한다.
- Heap은 크기 조절이 가능하지만, 크면 클수록 GC 부하가 커진다.
- Method Area(Metaspace)는 JVM의 클래스 정보 저장소이며, Java 8 이후에는 Native 메모리 기반으로 관리되어 안정성이 높아졌다.
- JVM 성능 최적화의 핵심은 Heap과 Metaspace의 균형 설정이다.
'지식을 쌓아보자 > JAVA' 카테고리의 다른 글
| JVM 구성 파헤치기(작성 중) (0) | 2025.08.25 |
|---|---|
| Java와 C++ 메모리 관리 차이(JVM을 위한 기초) (0) | 2025.08.25 |