JVM, 자바코드 실행과정
JVM
바이트코드(.class파일)를 OS에 맞는 기계어로 변환
이를 클래스 로더에서 읽어와 메모리 영역에 저장/관리
이를 실행엔진에서 바이트코드 명령어 단위로 읽어들여 실행하며
가비지 컬렉터로 메모리 관리를 하는 가상머신
- 자바 프로그램은 설치된 컴퓨터의 OS에 대해 독립적
- 컴퓨터에서 프로그램을 직접 실행하는게 아니라 인터페이스 역할을 하는 JVM에서 실행되기 때문
- 자바의 탄생 이유이자 목적
컴파일
javac TargetFile.java
- java 파일을 class 파일로 컴파일
실행
java TargetFile.class
- JVM 구성요소인 클래스로더가 TargetFile.class 파일을 메모리상의 JVM으로 가져옴
- 내부적으로 classLoader -> Byte Code Verifier(바이트코드 변조 확인) -> Execution Engine에서 실행되는 구조
- Execution Engine에서 클래스파일(바이트코드로 구성)을 기계어로 변경해서 명령어 단위로 실행
- 명령어단위실행방식
- Interpreter 방식 : 명령어를 하나씩 수행하는 방식(변환되면 바로 실행)
- JIT(Just In Time compiler) 방식 : 전체 바이트코드를 네이티브 코드로 변환하고 그 이후에는 네이티브 코드로 실행하는 방식
바이트코드
특정 하드웨어가 아닌 가상 컴퓨터에서 돌아가는 실행 프로그램을 위한 이진 표현법. 특정 하드웨어에 대한 의존성을 줄이고,
인터프리팅도 쉬운 결과물을 생성하고자 하는 프로그래밍 언어에 의해, 출력코드의 한 형태로 사용된다.
쉽게 말해서 자바는 OS에 종속적이지 않기 위해 JVM이 이해할 수 있는 언어인 바이트코드 형태로 제공되고 바이트코드와 JVM이 있으면 OS에 종속적이지 않고 실행된다.(.java 파일은 확장자가 java인 텍스트 파일)
JIT 컴파일러
- 기존 클래스파일(바이트코드)를 실행하는 방법은 Interpreter 방식이 기본이다. Interpreter방식은 명령어 하나하나 실행 속도는 빠르지만 전체 코드 관점에서 보면 실행 속도가 느린 단점이 있다. 해당 문제를 해결하기 위해 나온 방법이 JIT 컴파일러, JIT 컴파일러는 런타임 시 .class파일(바이트코드)를 네이티브 기계어로 한번에 컴파일 후 사용하는 개념
- 전체 컴파일 후 캐싱, 이후 변경된 부분만 컴파일하고 나머지는 캐시에서 가져다가 실행. 변경 부분만 컴파일하기 때문에 코드 수행속도가 Interpreter 방식에 비해 빠르다.
- JVM에 여러종류가 있는데(오라클, IBM 등) 그 중 오라클 핫스팟 VM
- 오라클 핫스팟 VM은 코드를 분석한 후 컴파일이 필요한 부분만 JIT 컴파일러를 통해 컴파일하고 나머지는 인터프리터 방식으로 동작한다. 그리고 컴파일된 코드라도 자주 호출되지 않는다면 네이티브 코드(컴파일된 코드)에서 제거하고 해당 부분은 인터프리터 방식으로 동작
JVM 구성요소
Class Loader
클래스 파일을 로드하는데 사용되는 하위 시스템
Method Area
- JVM Method Area는 메타데이터, 상수 런타임풀, 메서드에 대한 코드와 같은 클래스 구조를 저장
- 다른 스레드에서도 활용가능한 공유자원
Heap
- 모든 개체, 관련 인스턴스 변수 및 배열은 힙에 저장
- 메모리는 여러 스레드에 걸쳐 공유됨
JVM Language Stacks
- 로컬 변수를 저장하고 부분적인 결과를 얻음
- 각 스레드에는 자체 JVM 스택이 있으며, 스레드가 생성될 때 동시에 생성됨
- 메서드를 호출할 때마다 새 프레임이 생성되고, 메서드 호출 프로세스가 완료되면 삭제됨
- 스택은 공유자원이 아니므로 Thread Safe
PC Register
- PC 레지스터는 현재 실행 중인 Java 가상 시스템 명령의 주소를 저장
- 자바에서는 각 스레드에 별도의 PC 레지스터가 존재함
Native Method Stack
- 네이티브 라이브러리에 따라 네이티브 코드 명령을 보관. 자바 대신 다른 언어로 쓰여있음
Execution Engine
- 런타임 데이터 영역에 할당된 바이트코드는 실행엔지에 의해 실행됨
- 실행엔진은 바이트코드를 읽고 조각 별로 실행함
Native Method Interface
- JVM에서 실행 중인 Java 코드가 라이브러리 및 네이티브 애플리케이션으로 호출할 수 있도록 하는 프로그래밍 프레임워크
Native Method Libraries
- Native Libraries는 실행 엔진에 필요한 Native Libraries(C, C++)의 모음
JDK와 JRE 차이
- JRE는 자바 어플리케이션을 수행하기 위한 SW(JVM과 Class Libraries등 최소한의 환경)라고 볼 수 있고 JDK는 JRE + 개발에 필요한 SW를 모아놓은 좀 더 큰 범위의 SW
Comments