JVM 이란?
C와 C++ 등과 같은 언어는 프로그램이 컴파일이 되면 해당 OS에 종속된 기계어 코드로 변환되어 다른 OS에서 실행을 할 수 없지만, 자바에서는 각기 다른 OS에서 자바 프로그램을 실행할 수 있습니다. 그 이유는 바로 JVM이 중계자 역할을 하여 어느 OS에서든 자바 프로그램이 컴파일되어 실행될 수 있기 때문입니다.
1. 자바 프로그램 실행 과정
- 자바 컴파일러를 통해 Java Source를 컴파일합니다.
- 컴파일된 Class 파일을 Class Loader에게 전달합니다.
- Class Loader는 동적로딩을 통해 ByteCode들을 JVM에 있는 Runtime Data Area에 로딩합니다.
- Execution이 Runtime Data Area에 있는 ByteCode들을 명령어 단위로 한 라인씩 해석하고 실행합니다.
- 컴퓨터가 이해할 수 있도록 Excution은 ByteCode를 기계가 실행할 수 있는 기계어로 변경하는데 이때 Interpreter와 JIT가 사용됩니다.
- 만약 실행 중에 Native(예: C언어)로 실행되는 것이 있다면 Native Method Interface 통해 실행될 수 있습니다.
ByteCode(바이트코드)란?
List of Java bytecode instructions - Wikipedia
- 자바 컴파일러에 의해 변환되는 코드로 명령어 크기가 1byte라 바이트코드라 부른다.
- 같은 명령어 집합을 사용하여 JVM에 의해 OS나 개발환경에 관계없이 실행 가능하게 한다.
- 고급언어로 작성된 소스코드를 JVM이 이해할 수 있는 중간 코드로 컴파일한 것을 말한다.
2. JVM의 구성요소
2-1. Class Loader
Class Loader는 JVM의 중요한 구성 요소 중 하나로 총 세 가지 역할이 수행되며 자바 프로그램에서 클래스를 동적으로 로드하는 역할을 담당합니다. 필요한 클래스를 찾고, 클래스 파일을 읽어 Link를 통해 동적으로 Runtime Data Area에 배치합니다.
역할 | 설명 |
로딩 (Loading) | Class 파일을 읽어와 JVM의 메모리에 로드하는 단계 |
링크 (Linking) | 로드된 Class에 대한 준비 작업이 수행되는 단계 |
초기화 (Initialization) | Class의 정적 변수들이 실제 값으로 초기화 |
2-2. Runtime Data Area
실행 중인 프로그램에 대한 데이터를 관리하기 위해 사용되는 메모리 영역을 말합니다. 총 5가지 영역으로 구분이 되며 각각의 영역은 특정 목적을 가지고 있습니다.
영역 | 설명 | |
모든 스레드가 공유 | Method Area | 클래스 정보, 변수 정보, static으로 선언한 변수가 저장되며 프로그램 시작부터 종료될때까지 유지 |
Heap | 동적으로 생성된 객체가 저장되는 영역으로 GC의 대상이 되는 공간 | |
각 스레드 별로 생성 | Stack | 지역변수나 메서드의 매개변수, 참조변수, 임시적으로 사용되는 변수, 메서드의 정보가 저장 즉, 사용되고 금방 사라지는 변수가 저장 |
PC Register | 스레드가 시작될 때 생성되며 스레드가 어떤 부분을 어떤 명령어로 수행할지를 저장하는 공간으로 현재 수행 중인 JVM 명령의 주소를 갖는다. | |
Native Method Stack | Java가 아닌 다른 언어로 작성된 코드를 위한 공간, 즉 Java Native Interface를 통해 호출되는 Native Method를 저장하는 공간 (ex : C언어로 작성된 메서드) |
2-3. Execution
Execution은 Class Loader에 의해 Runtime Data Area에 배치된 ByteCode들을 하나씩 가져와 실행하거나 Garbage Collector를 실행시켜 주는 역할을 합니다. ByteCode를 실행하기 위해서는 ByteCode를 기계가 실행할 수 있는 기계어로 변경하여 사용되는데 Interpreter와 JIT(Just - In - Time) 두 가지 방법이 있습니다.
Interpreter | 하나의 명령어를 읽고 해석하여 실행하는 방식 |
JIT(Just - In - Time) | 빈번하게 실행되는 명령어를 기계어로 번역하여 캐시에 저장하여 사용 |
Garbage Collector | 이미 할당된 메모리에서 더 이상 사용하지 않는 메모리를 해제함 |
JIT(Just - In - Time) 컴파일러란?
- Interpreter의 단점을 보완하기 위한 컴파일러
- 바이트코드를 CPU가 이해할 수 있는 언어로 바꾸는 컴파일러
- 자주 쓰이는 바이트코드를 기계어 코드로 변경하여 캐시에 저장 후 필요 시 캐시에서 가져와서 사용
- 프로그램을 오래 실행할수록 프로그램의 실행 속도가 빨라진다.

- 자주 쓰이는 바이트코드가 처음 들어왔을 때 동작 과정
- (1) JIT Compiler에 의해 기계어로 번역
- (2) 번역된 기계어를 cashe에 저장
- (3) 번역된 기계어를 전달
- 자주 쓰이는 바이트코드가 다시 들어왔을 때 동작 과정
- (4) 해당 바이트코드가 들어온 것을 확인
- (5) cache에서 바이트코드에 해당되는 기계어를 가져옴
- (6) 번역된 기계어를 전달
2-4. JNI(Native Method Interface)
JNI는 자바 프로그램에서 자바 언어 외의 네이티브 언어와 상호 작용할 수 있는 인터페이스를 제공하는 기술입니다. JNI를 사용하면 자바 코드에서 네이티브 코드(ex : C언어, C++ 등)를 호출하고 네이티브 코드에서 자바 프로그램으로부터 호출되어 실행될 수 있습니다.
2-5. Native Method Libraries
Native Method Libraries는 JNI를 사용하여 자바 언어 외의 네이티브 언어로 작성된 코드를 자바 프로그램에서 사용할 수 있도록 제공되는 라이브러리입니다.
3. JDK와 JRE
자바 프로그램을 개발하고 실행하는 데 필요한 도구와 환경을 제공하는 소프트웨어 패키지입니다.
3-1. JDK(Java Development Kit)
JDK는 자바 애플리케이션 및 컴포넌트를 개발하기 위해 필요한 도구와 라이브러리들의 집합입니다. JDK에는 다음과 같은 주요 구성 요소가 포함되어 있습니다.
구성 요소 | 설명 |
컴파일러(Compiler) | - 자바 소스 코드(.java 파일)를 바이트코드(.class 파일)로 변환하는 역할을 수행 - 자바 언어의 문법을 검사하고 오류를 확인하며 컴파일된 코드를 생성한다. |
디버거(Debugger) | - 자바 프로그램의 실행 과정을 디버깅하고 오류를 찾는데 사용 |
개발 도구(Tools) | - 개발자가 자바 애플리케이션을 작성하고 관리하기 위한 다양한 도구를 제공 - 통합 개발 환경(IDE), 빌드 도구, 프로파일링 도구 등 |
라이브러리 및 클래스 파일 | - 자바 프로그램 개발에 필요한 라이브러리와 클래스 파일이 포함 |
JRE | - 자바 애플리케이션을 실행하기 위한 실행 환경을 제공 |
3-2. JRE(Java Runtime Environment)
JRE는 자바 애플리케이션을 실행하기 위한 실행 환경을 제공하고 개발 환경을 제공하지 않습니다. JRE에는 다음과 같은 주요 구성 요소가 포함되어 있습니다.
구성 요소 | 설명 |
JVM | JVM은 자바 바이트코드를 기계어로 번역하고 실행하는 역할을 담당 |
Runtime Library | 자바 프로그램 실행에 필요한 런타임 라이브러리 |
'Backend > Java' 카테고리의 다른 글
[Java] 자바 8 - (2) Stream : 데이터 처리 연산 (0) | 2023.07.23 |
---|---|
[Java] 자바 8 - (1) Stream : 람다 표현식의 등장 배경 (0) | 2023.07.23 |
[Java] Lambda Expression(람다 표현식) (0) | 2023.07.22 |
[Java] ThreadLocal (1) | 2023.07.16 |
[Java] Garbage Collector (0) | 2023.07.16 |