이 글은 The Java® Language Specification과 The Java® Virtual Machine Specification의 내용을 바탕으로 작성되었습니다. 중요 부분을 요약하는 방식으로 작성되었으며, 상세한 내용은 위 Specification에서 학습하실 수 있습니다.
정의
자바 프로그램을 실행하기 위한 가상의 컴퓨팅 환경
JVM?
- Java Virtual Machine
- 자바 플랫폼의 핵심
- Java는 JVM 위에서 동작 → 플랫폼 독립성, 크로스 플랫폼
- 컴파일된 자바 소스 코드(Bytecode) 실행
- 추상적인 컴퓨팅 머신 → 명령어 세트와 메모리 영역을 다룸
- 자동 메모리 관리, 가비지 컬렉션 수행
- 멀티스레드 환경에서 스레드 관리, 동기화 제공 → 동시성 지원
- 악성 코드로부터 사용자의 시스템을 보호하기 위한 보안 기능 제공
- Just-In-Time 컴파일러(Bytecode → 기계어) 사용 → 성능 향상
JVM 아키텍처

- Class Loader
- 필요한 클래스 및 인터페이스를 동적으로 로드
- 클래스 파일을 찾고 로드하여 JVM의 메모리 영역에 올림
- Runtime Data Areas
- Method Area: 클래스 정보, 정적 변수, 상수 및 메서드 코드 등의 정보 저장
- Heap Area: 동적으로 할당된 객체 인스턴스와 배열이 저장되는 공유 메모리 영역
- Stack Area: 메서드 호출과 관련된 정보 저장, 각 스레드마다 별도의 스택 생성
- PC Registers: 각 스레드마다 현재 실행 중인 명령의 주소 저장
- Native Method Stack: 자바 코드가 아닌 다른 언어로 작성된 네이티브 메서드의 호출과 관련된 정보 저장
- Execution Engine
- 자바 프로그램을 실행하는 핵심 컴포넌트
- 자바 바이트코드 → 기계어 변환, 실행
- Interpreter
- 바이트코드를 한 줄씩 해석하고 실행
- 느리지만, 플랫폼에 독립적이고 즉시 실행 가능
- JIT 컴파일러(Just-In-Time Compiler)
- 인터프리터의 성능을 향상시키기 위해, 반복되는 코드 블록을 실시간으로 기계어로 컴파일하여 캐시에 저장, 이후 해당 코드 블록은 기계어로 직접 실행 → 빠른 실행 속도 제공
- Garbage Collector(가비지 컬렉터)
- 자동 메모리 관리를 위해 가비지 컬렉터 사용
- 더 이상 참조되지 않는 객체를 식별하고 제거하여 메모리 회수
- Java Native Interface(JNI)
- 네이티브 코드(주로 C 또는 C++로 작성된 코드)와 상호 작용하기 위한 인터페이스 제공
- 자바 언어와 다른 언어 간 통합 가능
JVM 동작 과정
- 클래스 로딩: 필요한 클래스 파일을 클래스 로더를 통해 로드
- 클래스 링킹: 로드된 클래스 파일 검증, 준비 작업을 수행, 필요한 경우 다른 클래스와 인터페이스와의 참조 해결
- 클래스 초기화: 링킹 후, 클래스의 static 변수와 static 블록을 초기화, 이 단계에서 클래스의 초기화가 진행됨
- 메서드 호출: 클래스 초기화 완료 시, main 메서드를 찾아 실행합니다. main 메서드는 public, static, void로 선언되어야 하며, String 배열을 매개변수로 가져야함
- 실행 엔진: main 메서드의 바이트코드를 실행 엔진을 통해 해석하고 실행, 실행 엔진은 인터프리터 또는 JIT 컴파일러를 사용하여 바이트코드를 기계어로 변환하고 실행
- 객체 관리: JVM은 동적으로 할당된 객체와 배열을 힙 영역에 관리, 가비지 컬렉터를 사용하여 더 이상 필요하지 않은 객체 자동 회수