Execution Engine은 JVM이 클래스 파일(.class)을 로드하고 실행하는 런타임 모델입니다. 클래스 로더에 의해 JVM으로 로드된 클래스 파일(바이트 코드)은 런타임 데이터 영역의 메서드 영역에 배치됩니다. JVM은 이 메서드 영역의 바이트 코드를 Execution Engine에 제공하여 코드를 실행합니다. Execution Engine은 이 바이트 코드를 실행하여 프로그램이 실제로 동작하도록 합니다.
Execution Engine은 바이트 코드를 명령어 단위로 읽어서 실행하는데, 두 가지 방식을 혼합하여 사용합니다.
인터프리터는 바이트 코드를 한 줄씩 읽고, 운영체제가 실행할 수 있도록 기계어로 변환합니다. JVM 인터프리터는 런타임 중에 바이트 코드를 한 라인씩 읽고 실행합니다. 이 방식은 변환 속도가 느려서 반복문 같은 경우에도 매번 코드를 읽고 번역해야 하기 때문에 성능이 떨어집니다.
JIT 컴파일러는 인터프리터의 속도 문제를 해결하기 위해 도입된 기능입니다. 자주 실행되는 바이트 코드를 런타임 중에 기계어로 컴파일하여 성능을 향상시킵니다. JIT 컴파일러는 코드의 실행 빈도를 분석하여 자주 사용되는 코드를 네이티브 코드로 변환하고 캐싱합니다. 이후 변경된 부분만 컴파일하고, 나머지는 캐싱된 코드를 사용하여 실행 속도를 최적화합니다.
초기 JVM에서는 모든 바이트 코드를 직접 기계어로 해석하여 성능 문제가 있었습니다. 이를 해결하기 위해 JDK 1.3에 HotSpot VM이 도입되었고, JIT 컴파일러를 통해 바이트 코드를 최적화된 네이티브 코드로 변환하여 실행 속도를 크게 개선했습니다.
JVM은 실행되는 코드를 주의 깊게 관찰하고, 자주 시행되는 부분을 분석하여 최적화합니다. 컴파일은 백그라운드 스레드에서 이루어져 프로그램 실행을 방해하지 않습니다.
컴파일 임계치는 코드가 JIT 컴파일러에 의해 컴파일될 기준을 의미합니다. 코드의 실행 빈도가 컴파일 임계치를 만족하면, 해당 코드는 JIT 컴파일러에 의해 컴파일되어 최적화된 네이티브 코드로 실행됩니다.
ref. https://www.ibm.com/docs/ko/sdk-java-technology/8?topic=reference-jit-compiler
https://mangkyu.tistory.com/343
https://mangkyu.tistory.com/301