JDK, JRE, JVM
JVM을 설명하려면 먼저 JDK에 대해 먼저 설명해야한다.
간략하게 설명하면 다음과 같다.
- JDK : Java로 애플리케이션을 개발하기위한 SDK. 개발할때 필요.
- JRE : 바이트 코드(정확히는 .class 파일. Java가 아니어도 됨.)를 실행하기 위한 환경.
- JVM : 바이트 코드를 실행시키는 가상 컴퓨터.
질문! 왜 굳이 JDK, JRE를 구분하여 만들었을까요?
목적이 다르다.
JDK는 개발자용으로 제공하는 소프트웨어고
JRE는 실행만을 위한 소프트웨어다.

그래서 JDK를 보면 JRE를 포함한 개발도구들이 포함되어있다.
우리가 흔히 사용하는 java, javac(컴파일러), jar 같은 명령어들 (bin 경로에 존재하는)이 개발 툴에 속한다. (bin 경로에 있다고 모두 JDK 에 해당하는건 아니다. java 같은 명령어는 JRE 설치만해도 포함된다.)
그밖에 lib(런타임에 필요한 라이브러리들), include(네이티브 코드용 헤더 파일들)등이 있다.

다음은 실제 JDK를 설치하고 디렉토리를 확인해본 내용들이다.



AI 로 해당 디렉토리를 분석해달라고 했을때의 답변이다. (참고)
- bin (JDK + JRE)
- 실행 파일들이 들어있는 디렉토리.
- JDK: javac(컴파일러), javadoc, javap 등 개발용 툴 포함.
- JRE: java(실행기), keytool, policytool 등 런타임 관련 툴 포함.
- include (JDK)
- C/C++ 네이티브 코드와 연동할 때 필요한 헤더 파일 제공.
- JNI(Java Native Interface) 개발 시 사용.
- jre (JRE)
- Java Runtime Environment 전체가 들어있는 디렉토리.
- JVM, 표준 클래스 라이브러리, 실행 관련 리소스 포함.
- JDK 안에 JRE가 포함되어 있으므로 이 디렉토리 존재.
- lib (JDK + JRE)
- JDK: 개발 도구들이 사용하는 라이브러리.
- JRE: JVM이 실행 시 필요한 표준 라이브러리(rt.jar 등).
- src.zip (JDK)
- Java 표준 라이브러리의 소스 코드 압축본.
- 학습이나 디버깅용으로 제공.
- javafx-src.zip (JDK)
- JavaFX 관련 소스 코드 압축본. GUI 개발용.
- man (JDK)
- 유닉스/리눅스 환경에서 사용하는 매뉴얼 페이지.
- 각 명령어(java, javac 등)의 설명서.
- LICENSE, THIRD_PARTY_README, ASSEMBLY_EXCEPTION, commitId.txt, version.txt
- 라이선스 및 버전 정보, 빌드 관련 문서.
- JDK/JRE 모두에 해당하는 메타 정보.
반면 JRE는 런타임만을 위한 소프트웨어다.
그래서 대표적으로 표준 라이브러리 파일(rt.jar 같은 미리 작성된 jar 파일), JVM이 여기에 속하게 된다.

(+추측의 내용)
공식적인 내용은 아니지만 과거에는 하드웨어 자원이 지금보다 훨씬 제한적이었고,
자바는 클라이언트/서버/임베디드 등 다양한 환경에 배포돼야 했다.
그래서 개발을 위한 완벽한 SDK(JDK)와 실행만을 위한 JRE를 구분하지 않았을까 싶다.
가장 큰 목적은 역할의 분리이겠지만 자원 절감이라는 효과도 있지 않았을까한다.
질문! 타 언어로 작성된(Kotlin, Scala로 작성된) 바이트 코드도 JRE로 실행이 가능한가요?
가능하다.
왜냐하면 JRE는 Java 파일을 실행하는게 아니기 때문이다.
.class 확장자인 바이트 코드를 기계어로 번역하는 역할을 한다.
그렇기에 클래스 파일(.class) 파일을 만들 수 있다면 타 언어로 작성되어도 실행이 가능하다.
추가 질문! 그럼 Java 라이브러리도 타 언어에서 실행이 가능한가요?
가능하다.
그래서 Kotlin에서도 import 문을 통해 Java 클래스를 호출한다.
이를 통해 JVM 위에서 돌아가는(.class 파일로 변경되는) 언어들은 서로 호환이 가능하게된다.
(JVM은 단순히 .class 파일을 실행하기만 할뿐.)
Java의 실행순서
(해당 그림을 봐야 JVM 질문이 가능해진다.)
다음 그림과 같이 .java 파일을 javac(컴파일러)가 컴파일하면
바이트 코드가 나오고
이를 JVM이 알아서 해석, 컴파일하면 기계어가 나온다.
이 기계어를 CPU가 실행하게 되는것이다.

질문! JVM 구성 요소에 대해 설명해주세요!
JVM은 크게 3가지 구성 요소로 이루어집니다. (Java 8 버전 기준)
- class loader
- bootstrap class loader : 기본 Java API 로드. (rt.jar 같은)
- extention class loader : 확장 라이브러리 로드. (jre/lib/ext)
- application class loader : 사용자가 작성한 클래스와 외부 라이브러리 로드.
- runtime data area
- Thread 공통
- Method Area : 클래스 메타 데이터들. 상수 풀, 메서드 코드들.
- Heap : 객체, 배열. GC 대상.
- Runtime Constant Pool
- Thread 별 별도
- PC Register : 현재 실행중인 명령어 주소 저장용 레지스터.
- JVM Stack : 스택 프레임 저장용.(지역 변수, 피연산자, 반환값 등)
- Native Method Stack : JNI 에서 사용하는 네이티브 코드용 Stack.
- Thread 공통
- execution engine
- Interpreter : 바이트코드를 한줄씩 실행. (디폴트)
- JIT Compiler (Just-In-Time) : 자주 실행되는 코드(핫 스팟)를 네이티브 코드로 컴파일하여 실행.
- Garbage Collector : 참조되지 않는 객체들 메모리에서 해제.
참고
JRE, JDK 관련
- https://aws.amazon.com/ko/what-is/java-runtime-environment/
- https://stackoverflow.com/questions/1906445/what-is-the-difference-between-jdk-and-jre
- https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jdkfiles.html
- https://inpa.tistory.com/entry/JAVA-%E2%98%95-JDK-JRE-JVM-%EA%B0%9C%EB%85%90-%EA%B5%AC%EC%84%B1-%EC%9B%90%EB%A6%AC-%F0%9F%92%AF-%EC%99%84%EB%B2%BD-%EC%B4%9D%EC%A0%95%EB%A6%AC
'Java' 카테고리의 다른 글
| Java의 탄생 (0) | 2026.03.11 |
|---|---|
| Stream API(임시저장용) (0) | 2024.08.08 |
| [객체지향설계원칙] DIP (0) | 2024.05.31 |
| [객체지향설계원칙] ISP (0) | 2024.05.31 |
| [객체지향설계원칙] LSP (0) | 2024.05.29 |