JVM이란?
Java Virtual Machine
OS에 종속받지 않고 CPU 가 Java를 인식, 실행할 수 있게 하는 가상 컴퓨터

- 원시코드(.java)는 CPU가 인식 못함 -> 기계어로 컴파일
- OS가 인식할 수 있는 기계어로 바로 컴파일 되는 것이 아님
- Java Compiler가 JVM이 인식할 수 있는 Java bytecode(*.class)로 변환
- 다음으로 JVM이 OS가 bytecode를 이해할 수 있도록 해석해줌
-> 따라서, JVM위에서 OS 상관없이 실행될 수 있는 것
OS에 종속적이지 않고, Java 파일 하나만 만들면 어느 디바이스든 JVM 위에서 실행할 수 있음
Java bytecode란?
가상 컴퓨터(VM)에서 돌아가는 실행 프로그램을 위한 이진 표현법
- 자바 바이트 코드(Java bytecode)는 JVM이 이해할 수 있는 언어로 변환된 자바 소스코드를 의미
- 자바 컴파일러에 의해 변환된 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불림
- 바이트 코드는 다시 실시간 번역기 또는 JIT 컴파일러에 의해 바이너리 코드로 변환
CPU가 이해하는 언어는 바이너리 코드, 가상 머신이 이해하는 코드는 바이트 코드
JIT 컴파일러란?
JIT 컴파일러는 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일러
- JIT 컴파일(just-in-time compliation) 또는 동적 번역(dynamic translation)
- 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일하여 기계어로 변경하고, 이후에는 해당 더 이상 인터프리팅 하지 않고 기계어로 직접 실행하는 방식
-> 기계어(컴파일된 코드)는 캐시에 보관하기 때문에 한 번 컴파일된 코드는 빠르게 수행
- JIT 컴파일러를 사용하는 JVM들은 내부적으로 해당 메서드가 얼마나 자주 수행되는지 체크하고 일정 정도를 넣을때에만 컴파일을 수행
정리
- 자바 컴파일러가 자바 프로그램 코드를 바이트 코드로 변환
- 실제 바이트 코드를 실행하는 시점에서 JRE이 바이트 코드를 JIT컴파일을 통해 기계어로 변환
JVM 구성요소

- 클래스 로더(Class Loader)
- JVM 내로 클래스 파일(*.class)을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈
- 런 타임시 동적으로 클래스를 로드하고 jar 파일 내 저장된 클래스들을 JVM 위에 탑재
- 실행 엔진(Execution Engine)
- 클래스를 실행시키는 역할
- 인터프리터(Interpreter)
- 자바 바이트 코드를 명령어 단위로 읽어서 실행
- 한 줄씩 수행하기 때문에 느림
- JIT 컴파일러(Just-in-Time)
- 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일하여 기계어로 변경
- 이후에는 해당 더 이상 인터프리팅 하지 않고 기계어로 직접 실행하는 방식
- 가비지 콜렉터(Garbage collector)
- 더이상 사용되지 않는 인스턴스를 찾아 메모리에서 삭제
- 런타임 데이터 영역 (Runtime Data Area)

- 프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간
- PC Register
- Thread가 시작될 때 생성되며 생성될 때마다 생성되는 공간
- 현재 수행 중인 JVM 명령의 주소를 가짐
- JVM 스택 영역
- 프로그램 실행과정에서 임시로 할당되었다가 메소드를 빠져나가면 바로 소멸되는 특성의 데이터를 저장하기 위한 영역
- Native method stack
- 자바 프로그램이 컴파일되어 생성되는 바이트 코드가 아닌 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역
- Method Area (= Class Area = Static Area)
- 클래스 정보를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장하기 위한 메모리 공간
- Runtume Constant Pool
- 상수 자료형을 저장하여 참조하고 중복을 막는 역할을 수행
- Heap

- 객체를 저장하는 가상메모리 공간
- Permanent Generation
- New/Young 영역
- 생명 주기가 짧은 “젊은 객체”를 GC 대상으로 하는 영역
- Eden
- Survivor
- Old
- 생명 주기가 긴 “오래된 객체”를 GC 대상으로 하는 영역
- New/Young/Old 영역의 인스턴스들은 추후 가비지 콜렉터에 의해 사라짐
JDK와 JRE 차이
JDK(Java Development Kit)
Java 를 사용하기 위해 필요한 모든 기능을 갖춘 Java용 SDK (Software Development Kit)
- JDK 는 JRE를 포함
- JRE에 있는 모든 것 뿐만 아니라 컴파일러(javac)와 jdb, javadoc 과 같은 도구 포함
JDK는 프로그램을 생성, 실행, 컴파일
JRE(Java Runtime Environment)
컴파일 된 Java 프로그램을 실행하는데 필요한 패키지
- JVM + 자바 클래스 라이브러리(Java Class Library) 등으로 구성