
자바 개발을 처음 시작하거나 사용하는 도중에 JRE, JDK, JVM이라는 용어를 자주 접하게 됩니다. 이번 글에서는 각각의 역할과 차이점을 명확히 정리해 보겠습니다. 😊
1. JVM (Java Virtual Machine)
정의
JVM은 자바 프로그램을 실행하는 가상 머신으로, 자바 바이트코드(.class 파일)를 해석하고 실행하는 역할.
주요 역할
- 로딩: 클래스 파일(.class)을 메모리에 로드합니다.
- 바이트코드 해석: 바이트코드를 기계어로 변환합니다.
- 메모리 관리: 자바 힙, 메서드 영역 등을 관리하고, 가비지 컬렉션을 수행합니다.
구조
- Class Loader: 클래스 파일을 로드합니다.
- Execution Engine: 바이트코드를 해석하고 실행합니다.
- Runtime Data Area: JVM이 실행 중 사용하는 메모리 영역으로, 주요 구성 요소는 다음과 같습니다.
- Heap: 객체가 저장되는 공간.
- Stack: 메서드 호출과 지역 변수를 저장.
- Method Area: 클래스와 메서드 정보 저장.
- PC Register: 실행중인 메서드 안에서 몇 번째 줄을 실행해야 하는지 나타내는 역할.
- Native Method Stack: C, C++ 네이티브 코드 실행 시 사용.
실행과정
- Java 소스 코드(.java) 작성
- javac 컴파일러가 바이트코드(.class)로 변환
- *클래스 로더(Class Loader)**가 .class 파일을 JVM 메모리에 로드
- 바이트코드 검증 (Verification)
- *실행 엔진(Execution Engine)**이 바이트코드를 해석 및 실행
- 필요하면 JIT 컴파일러가 네이티브 코드로 변환하여 실행 속도 최적화
- 실행 중 생성된 객체는 **GC(Garbage Collector)**가 관리
1) 클래스 로더 (Class Loader)
클래스 로더는 .class 파일을 로드하고 JVM이 실행할 수 있도록 메모리에 적재하는 역할을 합니다.
JVM의 클래스 로딩 과정은 Lazy Loading(필요할 때 로드) 방식으로 동작합니다.
📌 클래스 로더의 종류
- Bootstrap Class Loader (부트스트랩 클래스 로더)
- JVM이 기본적으로 제공하는 최상위 클래스 로더
- rt.jar(Java의 핵심 클래스, java.lang, java.util 등)를 로드
- Extension Class Loader (확장 클래스 로더)
- lib/ext/ 디렉토리의 JAR 파일을 로드
- 보통 확장 기능(Java API 외의 추가적인 라이브러리) 로딩에 사용됨
- Application Class Loader (애플리케이션 클래스 로더)
- classpath에 있는 사용자가 작성한 .class 파일을 로드
- Custom Class Loader (사용자 정의 클래스 로더)
- 개발자가 직접 만든 클래스를 동적으로 로드 가능
📌 클래스 로딩 과정
클래스 로딩은 다음 세 단계로 진행됩니다.
- Loading (로딩): .class 파일을 읽어 메모리에 올림
- Linking (링킹): 심볼릭 참조를 주소값으로 변경
- Verification(검증): .class 파일의 형식 및 바이트코드 검증
- Preparation(준비): 정적 변수(Static Variable) 할당 및 기본값 설정
- Resolution(해결): 심볼릭 참조를 메모리 주소로 변경
- Initialization (초기화): static 변수의 값이 할당되고, static {} 블록 실행
2) 런타임 데이터 영역 (Runtime Data Area)
JVM이 실행 중에 필요한 데이터를 저장하는 메모리 영역입니다.
📌 런타임 데이터 영역의 구성
영역 | 특징 |
Method Area (메서드 영역, 클래스 영역) | - 클래스의 바이트코드, 정적 변수, 상수 풀(Constant Pool) 저장 |
Heap Area (힙 영역) | - 객체와 인스턴스 변수 저장 (GC 관리) |
Stack Area (스택 영역) | - 메서드 호출 시 생성되는 지역 변수, 프레임(Stack Frame) 저장 |
PC Register (PC 레지스터) | - 현재 실행 중인 JVM 명령어 주소 저장 |
Native Method Stack (네이티브 메서드 스택) | - C, C++ 네이티브 코드 실행 시 사용 |
📌 각 영역의 역할
- 메서드 영역(Method Area)
- JVM이 로드한 클래스의 메타데이터(클래스 정보, 메서드 정보, static 변수, 상수 풀) 저장
- 클래스 로더가 클래스를 로드하면 이곳에 저장됨
- Thread 공유 영역
- 힙 영역(Heap)
- 객체 인스턴스와 인스턴스 변수 저장
- *Garbage Collector(GC)**가 불필요한 객체를 정리함
- Thread 공유 영역
- 스택 영역(Stack)
- 메서드 실행 시 할당되는 지역 변수, 메서드 호출 정보, 연산 결과 저장
- 스택 프레임(Stack Frame) 단위로 관리
- Thread 별로 개별 생성 (Thread-safe)
- 메서드 호출이 끝나면 자동으로 해제됨
- PC 레지스터(PC Register)
- 현재 실행 중인 JVM 명령어의 주소(Program Counter) 저장
- 각 Thread마다 하나씩 존재
- 네이티브 메서드 스택(Native Method Stack)
- Java가 아닌 C, C++ 네이티브 코드 실행을 위한 공간
- JNI(Java Native Interface)로 네이티브 코드를 호출할 때 사용
3) 실행 엔진 (Execution Engine)
실제 바이트코드를 실행하는 역할을 합니다. JVM 실행 엔진에는 다음 세 가지 방식이 존재합니다.
- 인터프리터(Interpreter)
- 바이트코드를 한 줄씩 해석하고 실행
- 실행 속도가 느리지만, 즉시 실행 가능
- JIT(Just-In-Time) 컴파일러
- 인터프리터 방식의 단점을 보완하여, 자주 실행되는 코드를 네이티브 코드로 변환하여 속도 향상
- 바이트코드를 한 번만 해석한 후 캐시하여 재사용함
- AOT(Ahead-Of-Time) 컴파일러 (GraalVM)
- GraalVM을 이용해 Java 코드를 네이티브 코드로 변환하여 실행 속도를 향상
- JVM 없이 실행할 수 있음
4) 네이티브 인터페이스 (Native Interface)
JVM이 Java 외부의 네이티브 코드(C, C++)와 상호작용할 수 있도록 해주는 인터페이스입니다.
- JNI(Java Native Interface): 네이티브 라이브러리 호출 가능
- JNA(Java Native Access): JNI보다 쉽게 네이티브 코드와 연동 가능
2. JRE (Java Runtime Environment)
정의
JRE는 자바 애플리케이션을 실행하기 위한 실행 환경입니다. JVM과 자바 프로그램 실행에 필요한 라이브러리 및 기타 파일로 구성됩니다.
구성 요소
- JVM: JRE에 포함되어 자바 프로그램을 실행합니다.
- 라이브러리(Java API): 자바 애플리케이션에서 사용하는 필수 클래스와 패키지(예: java.util, java.io 등).
JRE의 역할
개발이 아닌, 실행에 필요한 환경만 제공합니다. 자바 프로그램을 실행하고자 할 때, JRE만 설치되어 있어도 충분합니다.
3. JDK (Java Development Kit)
정의
JDK는 자바 애플리케이션을 개발 및 실행하기 위한 도구입니다. 개발자에게 필요한 JRE와 함께 컴파일러, 디버거 등의 개발 도구를 포함합니다.
구성 요소
- JRE: 실행 환경.
- javac (컴파일러): 자바 소스코드(.java)를 바이트코드(.class)로 변환합니다.
- jdb (디버거): 디버깅 도구.
- jar (아카이브 생성): JAR 파일을 생성하고 관리하는 도구.
- java (JVM 실행기): 바이트코드를 실행.
JDK의 역할
- 자바 프로그램 작성, 컴파일, 디버깅, 배포까지 전체 개발 사이클을 지원합니다.
JRE, JDK, JVM 비교
구성 요소 | 역할 | 관계 |
JVM | 자바 바이트코드 실행 | JRE와 JDK에 포함 |
JRE | 자바 프로그램 실행 환경 제공 | JVM + 라이브러리 |
JDK | 자바 개발 도구 제공 | JRE + 컴파일러 등 도구 |

- JVM: 자바 프로그램 실행의 핵심.
- JRE: 실행 환경 제공.
- JDK: 개발 환경 제공.
'Back_End > JAVA' 카테고리의 다른 글
자바에서 Generic(제네릭)을 쓰는 이유 (1) | 2024.12.27 |
---|---|
자바(Java)의 메모리 영역 (1) | 2024.12.19 |
자바의 가비지 컬렉터 (Garbage Collector) 🗑️ (0) | 2024.12.18 |
자바스크립트(JavaScript)의 스프레드 문법 (1) | 2024.12.18 |
자바(JAVA) Stack, Queue, Deque 란? (0) | 2024.12.18 |