javac
명령어를 사용하면 .class 파일을 생성할 수 있다.java
명령어로 .class 파일을 실행시킬 수 있다.! 정확히는 JRE라고 생각하면 된다. JRE는 JDK 내부에 포함되어 있으니까
JVM이 실행되고, JVM 내부 class loader를 이용해서 `시작 클래스를 생성`하고, `링크`하고, `초기화`하고, `main 메서드를 호출`한다.
JVM의 표준 구현인 바이트코드를 해석하면 프로그램 실행이 느려짐.
JIT 컴파일(just-in-time compliation) 또는 동적 번역(dynamic translation) 이라고 한다.
JIT 컴파일러는 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일러이다.
자바는 바이트코드로 한번 컴파일 하는 과정과, 바이트코드를 인터프리터 하는 방식 2가지를 진행한다. 가뜩이나 인터프리너 방식은 소스코드를 런타임시에 한줄 한줄 읽어 들여야 하는 방식 때문에 컴파일 방식보다 느리다.
(1) 컴파일 방식 : 소스코드를 한꺼번에 컴퓨터가 읽을 수 있는 native machine (기계)어로 변환
(2) 인터프리터 방식 : 소스코드를 빌드시에 암것도 하지 않다가, 런타임시에 한줄 한줄 읽어가며 변환, 둘 다 장단점이 있지만, 여기서 중요한건 자바는 컴파일과 인터프리터 방식을 모두 사용한다.
그래서 JIT 컴파일러를 도입하게 된 것 같다. 이미 한번 읽어서 기계어로 변경한 소스코드는 번역하지 않는다.
이런식으로 저장소에 저장을 한다는 개념이다. (코드 캐시는 JVM이 JIT 컴파일된 네이티브 코드를 저장하는 메모리 영역입니다. 이 영역은 메서드 영역이나 힙과는 별개의 공간으로 관리됩니다.) 정확히 다시 말하자면 반복되는 코드를 모두 컴파일러로 컴파일 시키는 것이다. 인터프리터의 역할을 보조한다고 생각하면 될듯 싶다.
java 명령어의 인자로 지정한 설정 옵션에 맞게 JVM이 실행되고 Class Loader를 이용해서 initial class를 create하고, initial class를 link하고, initialize하고, main 매서드를 호출한다.
용어 정리
JVM의 구성요서는 크게 3가지
Class Loader
클래스를 읽어오는 시스템 구조. 로딩 → 링크 → 초기화
- Runtime Data Area
- Stack
- PC Register
- Native Method Stack
- Heap
- 힙은 인스턴스화 된 모든 클래스 인스턴스와 배열을 저장, 객체를 저장하게 되는데, 모든 JVM 스레드에 공유 되는 공유 자원 이다. 힙에 저장된 할당된 메모리 회수 권한은 무조건 가비지 컬렉터(Garbage Collector)에 의해서만 회수가 가능하다.
- Method
- 런타임 상수 풀, 필드와 메서드 정보, 클래스 수준의 정보, 메서드 테이블이 저장되는 곳.
- 힙과 메서드 영역을 분리하였지만, jvm 스펙에서는 메소드 영역이 논리적으로 힙의 일부여서 가비지 컬렉션에 대상이 된다고 하지만, 강제적으로 메소드의 영역의 위치에 대해서 논하지 않는다고 한다. 즉, JVM 을 회사를 만드는 회사마다
- Excution Engine
- Interpreter
- JIT Compiler
- Garbage Collector
JDK : 자바 개발도구(java devlopment kit), JRE + 개발에 필요한 실행파일
JRE : 자바 실행환경(java runtime environment), JVM + 클래스 라이브러리
JDK를 통해서 byte code를 생성 JRE에게 토스
JRE를 사용해서 byte code를 java 명령어로 실행하게 된다.
JVM이 ‘실행’단계를 걸친다
크게 차이를 구분짓기보다 JDK 내부에 JRE가 포함되어 있다.