JVM 구조와 자바 메모리 올라가는 과정
면접에서 답변을 했으나 명확하게 답변하지 못 한 아쉬움이 있어 이번 기회에 제대로 정리하고 앞으로도 계속 볼 예정
| JVM Memory | |||
| 스레드 공유 | Heap | Method Area | |
| 스레드별 | PC Register | Native Method Stack | Stack |
Heap : 가장 크고 new로 생성된 객체 인스턴스와 배열이 위치 (GC의 대상)
Method Area : metaspace(클래스 정보), static 변수, 메서드 바이트코드, 상수 풀
PC Register : 현재 실행 중인 바이트코드 주소
Stack : 스레드별 생성, 지역변수, 메서드 호출 프레임
Native Method Stack : JNI를 통한 네이티브 메서드 호출 시 사용
JVM은 TLAB(Thread Local Allocate Buffer)라는 개념이 있다. new를 통해 객체 할당 시 각 스레드가 Heap 영역을 공유하면 잦은 context switching으로 인한 성능 저하가 올 수 있기 때문에 미리 각 스레드 별로 TLAB 공간을 할당해 new를 통한 객체 할당이 가능하도록 한다.
Java Stack은 해당 스레드의 함수 실행 순서가 쌓이고 함수 호출 시 push, 함수 종료 시 리턴되며 pop이 이뤄지기 때문에 자동으로 스코프 단위로 정리되기 때문에 GC 대상이 아니다.
자바 파일이 메모리에 올라가는 과정
자바(.java)가 실행되기까지의 전체 과정은 크게 컴파일 -> 클래스 로딩 -> 링킹 -> 초기화 -> 실행 단계로 나뉜다.
1. 정적 컴파일(javac)
Hello.java -> javac -> Hello.class(바이트코드)
2. 클래스 로딩(Class Loading)
Hello.class -> ClassLoader -> JVM 메모리(Method Area)
* JVM이 실행되면 ClassLoader가 .class 파일을 읽어 Method Area에 로드합니다.
*ClassLoader는 3단계 계층 구조:
* Bootstrap ClassLoader -> java.lang.* 등 핵심 클랙스
* Extension(Platform) ClassLoader -> 확장 라이브러리
* Application ClassLoader -> 우리가 작성한 클래스
3. 링킹(Linking)
링킹은 3단계로 이루어집니다
| Verification | 바이트코드가 JVM 스펙에 맞는지 검증 |
| Preparation | static 변수에 기본값 할당 (예: int → 0) static 변수 초기화가 아님 |
| Resolution | 심볼릭 레퍼런스를 실제 메모리 주소로 변환 |
4. 초기화(Initialization)
static변수에 실제 값을 할당하고, static {} 블록을 실행한다.
ex) static int count = 10; -> Preparation에서 0이었던 것이 이제 10으로 설정됨.
5. 실행(Execution)
Execution Engine이 byte code를 실행한다.
이 때 인터프리터 또는 JIT 컴파일러를 사용함
실행 흐름
1단계: javac 컴파일
Hello.java -> javac -> Hello.class(바이트코드)
2단계: JVM 실행
Execution Engine
처음에는 인터프리터로 실행
(한줄씩 해석 -> 느림)
반복 실행 감지!
(Hot spot발견)
JIT 컴파일러가 네이티브 코드로 변환(기계어라 빠름)
캐시에 저장(다음부터 바로 실행)
javac는 이식성을 위함이고 JIT는 성능을 위함
'IT 개발 > 개념 정리' 카테고리의 다른 글
| JWT 토큰에 대하여 (0) | 2026.03.04 |
|---|---|
| 낙관적 락, 비관적 락, Redisson Lock (0) | 2026.01.14 |
| JAVA Stream API에 대한 정리 (0) | 2026.01.09 |
| DB 개념 및 면접 내용 정리 (0) | 2026.01.08 |
| JAVA 면접 질문 공부 (0) | 2026.01.08 |