Class Loader에 의해 Method Area에 로드된 class file은 클래스의 정보를 담은 Constant Pool과 클래스의 동작을 정의한 Byte Code를 포함하고 있다. 이때, Execution Engine은 Method Area에 로드되어있는 Byte Code를 명령어 단위로 읽어와 실행한다.
JVM의 Execution Engine은 세 가지 부분으로 구성되어있다.
Byte Code를 한줄씩 읽어서 Native Code(기계어)로 번역하는 역할을 담당한다. 하지만 반복적으로 호출되는 메소드를 매번 번역해야하기 때문에 효율성이 떨어져 JIT Compiler를 도입했다.
JIT : Just In Time
JIT Compiler는 Interpreter와 같이 Byte Code를 Native Code로 번역하는 일을 담당한다. 하지만 Interpreter와 달리 매번 코드를 번역하지 않고, 자주 반복되는 코드는 Native Code로 번역하여 캐시(Native Method Stack)에 저장해두었다가 같은 코드가 나왔을 때 캐싱을 통해 이미 번역된 Native Code를 사용하여 효율성을 높였다.
JVM Execution Engine은 초기에 Interpreter방식으로 동작하다가 특정 조건(컴파일 임계치)을 만족하면 적절한 시점에 Byte Code전체를 Native Code로 바꾸어 캐시에 저장한다. 그 다음부터 Interpreter는 Native Code를 그대로 가져다 사용한다. Native Code를 실행하는 것이 인터프리팅 방식보다 빠르고, Native Code는 캐시에 보관하기 때문에 한번 컴파일된 코드는 계속 빠르게 수행된다
JIT Compile을 수행할 기준. method entry counter와 back-edge loop counter의 합
스택 프레임을 컴파일된 것으로 교체하여 속도를 개선하는 작업
대상 코드가 컴파일이 완료가 되었지만 최적화되지 않은 코드가 수행되고 있는 것이 발견된 경우 OSR을 수행한다
JIT Compiler는 위와 같은 구조로 동작한다.
JVM은 캐시공간을 효율적으로 사용하기 위해 모든 코드를 컴파일하지 않고, Profiling을 통해 자주 사용되는 코드를 찾아 그 빈도와 복잡도에 따라 코드의 레벨을 1~4로 나눈 뒤, 각 Level에 맞는 컴파일러를 사용하여 코드를 번역한다.
JVM의 JIT Compiler의 종류는 C1, C2 두 가지가 있다.
스타트업 시간과 메모리 공간 최적화
프로그램의 시작시간을 최소화하는데 집중하기 위해 Byte Code로부터 최대한 많은 정보를 뽑아 실제 동작하는 코드 블럭에 대한 최적화에 집중하며, 전체적인 최적화는 C2 Compiler가 담당한다
C1 컴파일러의 특징은 다음과 같다
C1 컴파일러가 컴파일을 수행하는 순서는 아래와 같다.
다수의 request를 빠르게 처리
장기 실행되는 서버측 엔터프라이즈 애플리케이션의 경우 C1 컴파일러로는 최적화가 충분하지 않을 수 있다. 따라서 C2 컴파일러는 부분적인 코드의 실행보다는 전체적인 성능 최적화에 중점을 둔다.
C2 컴파일러는 단기 실행되는 경량 클라이언트 애플리케이션보다 더 많은 프로파일링 데이터를 수집할 수 있기 때문에 더 고급 최적화 기술과 알고리즘을 적용할 수 있다.
C2 컴파일러의 특징은 다음과 같다
C1 컴파일러는 비교적 사용시간이 적은 클라이언트측 어플리케이션을 타겟으로 하여 빠른 컴파일을 통해 어플리케이션이 시작하는 시간을 줄이는 데에 초점을 맞춘 컴파일러이고,
C2 컴파일러는 사용시간이 긴 서버측 어플리케이션을 타겟으로, 컴파일에 걸리는 시간은 비교적 느리지만 높은 수준의 코드 최적화를 통해 전체적인 코드 실행시간을 줄이는 데에 초점을 맞춘 컴파일러이다.
C/C++는 개발자가 직접 메모리를 할당하고 해제해야 하지만(c : malloc/free, c++ : new/delete) Java는 사용자 대신 Garbage Collector가 동작하여 더이상 사용되지 않는 Heap영역의 인스턴스를 찾아 메모리를 해제한다.
JVM의 Garbage Collector에 대한 자세한 내용은 Garbage Collection에 정리했다.
종합적으로, Execution Engine은 이러한 세 가지 구성 요소를 통해 Java suika game 프로그램을 효율적으로 실행하고 관리합니다. Interpretation은 빠르게 시작할 수 있지만, JIT Compilation은 반복 코드에 대한 최적화를 통해 실행 시간 성능을 향상시킵니다. Garbage Collector는 메모리 관리를 담당하여 프로그래머가 명시적으로 메모리를 해제하는 부담을 줄여줍니다.
I'm glad you find the blog cool and that you feel fortunate to have stumbled upon it, discovering some awesome information along the way xciptv player.
When a Java program is compiled, it is transformed into bytecode, which is platform-independent. The execution engine takes this bytecode and interprets or geometry dash compiles it into machine code that can be executed by the underlying hardware.
Byte Code를 한 줄씩 읽어 기계어로 번역합니다. Geometry Dash 하지만 반복적으로 호출되는 메소드를 매번 번역해야 하기 때문에 성능 면에서 효율이 떨어질 수 있습니다.