JDK (Java Development Kit)
JRE + 컴파일러(javac) + 개발 도구(javadoc, jshell 등)
- Java 소프트웨어를 개발하기 위한 도구
JRE (Java Runtime Environment)
JVM + 라이브러리 + 제한된 도구
- 개발 오버헤드 없이 실행환경만 제공
- Java 실행환경 구성과 Java 애플리케이션을 실행할 수 있도록 구성,
- JRE만 있으면 어느 프로그램이든 실행가능(이식성)
- 컴파일해 생성된 클래스 파일을 JRE에 클래스 로더에서 로드하고, 필수 라이브러리를 결합해 JVM에 올리는 역할
JVM (Java Virtual Machine)
애플리케이션 실행 환경
- 스레드 생성, 실행, 스케줄링 담당
- 스레드 간 상호작용 관리
- 동기화 메커니즘 제공
- 자바 가상 머신(Java Virtual Machine, JVM)에서 실행
- JVM은 자바 런타임 환경(Java Runtime Environment, JRE)의 일부
- javac를 통해 컴파일된 클래스 파일(byte code)을 Java API와 함께 살행시키기 위한 가상머신이며 운영체제에 독립적
- JVM내에서 실행돼 안전(보안성) → 샌드박싱(sandboxing)
Java의 동작원리
- java코드는 컴파일 시 중간 언어인 바이트코드(bytecode)로 변환
💡 C, C++코드가 기계어로 컴파일 되는 것과 대비
1️⃣ JDK에서 작성된 코드를 컴파일해 생성한 클래스 파일을 JRE의 Class Loader에 로드
2️⃣ ClassLoader
JRE의 구성 요소로 javac 컴파일러로 .java 소스코드를 컴파일하여 Byte코드를 생성하고 해당 .class 파일을 ClassLoader가 JVM에 동적 로드하는 역할을 함
(1) Loading
- Bootstrap ClassLoader : 최상위 클래스 로더, Object 클래스 및 자바 API 로드(jre/lib/rt.jar (Object.class, String.class 등))
- Extension ClassLoader : 기본 자바 API를 제외한 확장 클래스들을 로드(jre/lib/ext/.jar , java.ext.dir/.jar (ZipInfo.class 등))
- Appication ClassLoader : 개발자가 직접 작성한 클래스를 로드(ClassPath : -classpath , -cp , Manifest)
- JVM에 클래스가 메모리에 로드 되었는지 확인후 로드가 안되어있으면 ClassLoaderRunner에 요청
- ClassLoaderRunner가 ApplicationClassLoader에게 Class 로드 요청
- ApplicationClassLoader는 직접 로드하지 않고 상위인 ExtensionClassLoader에게 위임
- ExtensionClassLoader는 직접 로드하지 않고 상위인 BootstrapClassLoader에게 위임
- BootstrapClassLoader는 rt.jar에 클래스가 존재하는지 확인
- 존재 한다면 클래스를 로드후 반환
- 없다면 하위 클래스로 내려가 해당 ClassLoader가 맡은 클래스 여부 확인하는 작업을 반복
- 최하위 클래스에서 존재하지 않을 경우 ClassNotFoundException이 발생
(2) Linking
- Verify : 컴파일 결과 검증, .class 파일 형식 검증
- Prepare : 메모리를 준비, JVM은 클래스 또는 인터페이스의 정적 변수를 메모리에 로드 후 기본 값 설정
- Resolve : Compile Time 에 자바 클래스는 다른 클래스의 실제 주소 값을 알지 못함, 실제 주소값 대신 Symbolic references가 대체함, 런타임 constant poll에 symbolic references의 구체적인 값 지정
(3) Initialization
- 모든 정적 변수가 기본 값에서 지정된 값으로 초기화
- block이 위에서 아래로, 부모에서 자식으로 실행
3️⃣ JVM
(1) Runtime Data Areas
ClassLoader가 Bytecode를 로드하는 메모리 영역, Thread로 영역이 구분됨
Thread 공유 영역
- Heap Area : Heap Memory 영역, 인스턴스, 객체 배열 등 동적으로 저장하는 공간, GC의 대상
- Method Area : ClassLoader가 적재한 클래스의 메타 데이터를 저장
- 타입의 전체 이름/타입의 클래스, 인터페이스 여부
- Runtime Constant Poll (타입의 모든 상수 정보를 가짐, 타입,필드, 메서드의 모든 심볼릭 참조 정보)
- Field Information(필드 타입, 필드 제어자)
- Method Information(method 명, return 타입, 파라미터 수, 타입, 제어자 등)
- Class Variable(static 키워드로 선언된 변수, 참조변수만 저장하고 실제 인스턴스는 Heap에 저장)
Thread 별 생성 영역
- PC Register : 현재 수행중인 JVM Instruction 주소를 가짐
- JVM Stack Area : Thread 의 메서드가 호출 시 stack frame의 정보, 메서드 호출 주소, 매개변수, 지역변수 같은 정보를 저장하고, 종료 시 stack point 에서 제거
- Native Method Stack : Native Code(C,C++등)을 위한 별도의 stack
※ JVM은 stack based 기반
(2) Execution Engine
Runtime Data Areas에 할당된 bytecode를 읽고 Execution Engine이 실행
1. Interpreter
- byte code를 한 줄씩 읽어나가면서 machine code로 해석하고 실행
- 장점 : JVM 시작속도가 빠름
- 단점 : 중복 코드는 효율이 떨어지므로 이 경우 JIT Compiler 이용
2. JIT(Just-In-Time) Compiler
- 함수나 파일 단위로 byte code를 machine code로 컴파일
- 동일한 바이트 코드 블록이 필요한 경우 캐시
- 동일한 코드를 여러번 호출시 기존에 번역한 코드를 재사용하므로 오버헤드가 적고 실행 속도가 빨라짐
- 런타임에 바이트코드를 기계어로 해석하여 실행
- 처음에는 Interpreter로 실행을 시작하고 반복 호출되는 메서드나 루프가 발견되면 JIT가 개입
3. Garbage Collection
- 동적으로 할당한 메모리 영역(Heap Area( 중 사용하지 않는 영역을 자동을 찾아서 메모리를 해제
(3) Native Method Interface (JNI)
Native Method Libraries와 상호작용하며 Execution Engine을 위한 Native Libraries를 제공
- Java 코드와 C/C++ 등 Native Code 간의 연결 고리 역할을 하는 인터페이스
(4) Native Method Library
Execution Engine에서 필요한 Native Libraries 모음
- JNI를 통해 호출되는 네이티브 코드가 실제로 구현되어 있는 라이브러리 파일들
'Java' 카테고리의 다른 글
Comparable (java.lang), Comparator (java.util) (1) | 2025.04.30 |
---|---|
Collection 프레임워크 (0) | 2025.04.29 |
데이터 타입 분류 - JAVA (0) | 2025.04.20 |
제어문 - JAVA (0) | 2025.04.15 |
[ Map ] key값을 기준으로 정렬 (0) | 2025.01.25 |