[JAVA] JVM 구조
JVM 개념
- Java Virtual Machine(자바 가상 머신)
- 자바 애플리케이션 실행을 위한 가상 컴퓨터
- 자바 소스 코드를 컴퓨터가 이해할 수 있는 방식으로 해석(Interpreter)
- 바이트 코드로 이뤄진 [.class] 파일 해석&실행
- 자바의 플랫폼 독립성을 보장
- 자바가 운영체제와 직접 소통X → JVM을 통해 간접 소통
- JVM은 플랫폼에 종속(OS마다 다르게 설치)
자바 코드 실행 과정
[.java] –javac–> [.class] –JVM–> 실행
JVM 구조
Class Loader –> Runtime Data Area <–> Execution Engine
1. Class Loader
.class파일을 읽어 Method Area에 로드
2. Runtime Data Area (메모리 구조)
1) Method Area
- 클래스가 처음 로드될 때 생성되어 JVM 종료까지 유지
- 하나의 Method Area 존재 → 모든 스레드에 공유
- 클래스 메타 정보, static 변수, final 상수, 필드 정보(값X), 메서드 바이트코드 저장
2) Heap Area
new키워드로 생성한 객체(인스턴스)를 저장- Method Area에 로드된 클래스 메타정보를 참조
- 상속받은 필드 값을 포함하여 객체 저장 → 업캐스팅 시에도 부모와 자식 필드 값이 모두 초기화 되어 저장
- 참조변수가 가리키는 객체의 실제 타입을 기준으로 Method Area에서 메서드 탐색 → 동적 바인딩
- 실제 타입에 메서드가 없으면 상위 클래스 방향으로 탐색
- Method Area에 로드된 클래스 메타정보를 참조
- Garbage Collection으로 메모리 자동 관리
- 참조가 끊기면 제거
- 하나의 Heap Area만 존재 → 모든 스레드에 공유
3) Stack Area
- 메서드나 생성자 호출 시 생성되는 스택 프레임 저장
- 스택 프레임: 매개변수, 지역변수, 참조변수(Heap 객체를 가리키는 참조)
- 호출 종료 시 스택 프레임 제거
- 마지막 실행 메소드(생성자) 먼저 제거(LIFO)
- 빠르지만 제한적 메모리 공간
- 스레드당 한 개 → 스레드 별로 독립
4) PC Register(Program Counter Register)
- 스레드가 다음에 실행할 바이트코드 위치를 기억하기 위한 레지스터
- 각 스레드가 실행 중인 메서드의 바이트코드 주소 & 다음 실행할 메서드의 바이트코드 주소 저장
- 스레드당 한 개
- 멀티스레드 환경에서 실행 흐름 복원을 위해 사용
5) Native Method Stack
- Java가 아닌 네이티브 코드를 실행할 때 사용하는 스택
- 네이티브 코드: C/C++, OS 의존, 자바와 다른 스택 구조
- ex.
System.out.println("hello")- 내부에서 네이티브 코드 호출
- ex.
- 네이티브 코드: C/C++, OS 의존, 자바와 다른 스택 구조
3. Execution Engine
- JVM의 실행 주체
- 바이트코드 해석(기계어 변환)
- 스택 프레임 생성
- Mathod Area를 읽어 메서드 호출 → 스택 프레임 생성 → Stack Area에
push→ 메서드 종료 →pop으로 제거
- Mathod Area를 읽어 메서드 호출 → 스택 프레임 생성 → Stack Area에
- CPU 실행 요청
- Interpreter/JIT 실행
1) Interpreter
- 바이트코드를 한 줄씩 해석해서 실행
2) JIT Compiler(Just-In-Time)
- 반복 실행 코드를 감지하여 기계어로 캐싱 후 재사용 → 성능 향상
Leave a comment