JIT Compiler
[ JIT Compiler 란? ]
JAVA 의 성능을 증대시키기 위한 런타임 환경의 요소이다.
런타임 중, 바이트 코드를 기계어 코드로 컴파일 해준다.
[ JIT Compiler 개요 ]
개요 1.
JAVA 프로그램은 다양한 컴퓨터 구조(OS) 에서 JVM 이 인터프리팅 할 수 있는
바이트 코드를 가진 클래스로 구성된다.
개요 2.
런타임 환경에서, JVM 은 클래스 파일을 로드하고, 각 개별 바이트 코드의 의미를 결정하고
적절한 계산을 수행한다.
개요 3.
JIT 컴파일러는 런타임 때, 바이트코드 -> 기계 코드로 컴파일하여
JAVA 프로그램의 성능을 개선하는데 도움이 된다.
개요 Final.
인터프리터 : Java Code -> Bytes Code
JIT 컴파일러 : Bytes Code -> Machine Code
[ JIT 속성 ]
JIT 속성 1.
JIT 컴파일러는 기본값으로 수행되도록 셋팅 되어져있다.
메서드가 컴파일 되면, JVM 은 컴파일 된 메서드를 호출하면
인터프리팅 과정을 거치지 않고 컴파일된 메서드를 바로 호출한다.
--> 컴파일 된 메서드를 호출하면 이론상 프로세서와 메모리의 사용을 요구하지 않아 성능이 좋아진다.
JIT 속성 2.
JIT 컴파일러가 첫 컴파일을 수행할때는 프로세서 + 메모리를 필요로 한다.
JVM 이 처음 시작될 때 수 천개의 메서드가 호출되기 때문에 처음 시작에는 시작 시간이 늦어질 수 있다.
JIT 속성 3.
하지만, 실제로 모든 메서드가 처음 호출 된다고해서 컴파일 되는게 아니다!
각 메서드에 대해 JVM 은 Count 를 설정한다.
그리고 메서드가 호출될 때마다 Count 를 감소시켜 호출 횟수를 관리한다.
호출 횟수가 0에 도달하면 메서드에 관한 JIT 컴파일이 시작된다.
따라서 자주 사용하는 메서드는 JVM 의 시작 이후에 바로 컴파일되고
덜 사용하는 메서드는 훨씬 나중에 컴파일 되거나 컴파일 되지 않는다.
이 Count(임계값) 은 Application 시작 시간과 장기 성능 측면에서의 균형을 유지하기 위해 채택된 방법이다.
JIT 컴파일(최적화 단계)
JIT 컴파일러는 각 메서드를 다른 최적화 단계를 부여하여 컴파일한다.
최적화 단계
Cold, Warm, Hot, veryHot, Scorching
최적화 수준이 높을 수록 더 높은 성능을 제공하지만 컴파일 비용이 더 많이 들게 된다.
메서드의 기본 최적화 단계는 Warm 이지만, JIT 가 시작 시간을 개선하기 위해 Cold 단계로 다운그레이드 하기도 한다.
JIT 컴파일(추가)
다른 매커니즘을 통해 메서드를 더 최적화 하여 컴파일 할 수도있다.
hot, verHot, scorching 단계의 메서드들이 그 대상이다.
JIT 컴파일러는 비활성화 할 수 있지만 JIT 의 문제 진단을 위한 경우 등을 제외하곤 권장되진 않는다.
[ JIT 컴파일러가 코드를 최적화 하는 방법 ]
JIT 컴파일러에게 학습 시킬 것
컴파일을 위한 메서드가선택되면, JVM 은 JIT 에게 바이트 코드를 전달한다.
JIT 는 바이트코드의 문장을 정확하게 이해할 수 있어야한다.
그래서 JIT 가 메서드를 분석하는데 도움이 되도록 바이트 코드는, 기계 코드와 더 유사한 Tree 라는
내부 표현으로 재구성된다.
이 후 Trees 가 기계어로 번역이 된다.
BytesCode -> Trees -> MachineCode
JIT 컴파일러 성능 증대
JIT 컴파일러는 여러개의 컴파일 스레드를 이용하여 컴파일 작업을 수행할 수 있다.
JIT 컴파일 스레드는 시스템에서 사용되지 않고 있는 코어가 있을 경우에만 성능 향상을 제공한다.
JIT 컴파일 과정 (최적화 과정)
단계 - 1 : Inlining
인라인 작업은, A 라는 메서드가 있을때 이 메서드를 B라는 더 큰(더 자주 사용하는) 메서드나 클래스가 사용한다면
B가 담겨있는 트리에 A 라는 메서드를 병합하는 것이다.
이렇게하면 자주 실행되는 메서드의 호출 속도가 빨라지게 된다.
[ 인라인 정책 ]
Trivial inlining
Call graph inlining
Tail recursion elimination
Virtual call guard optimizations
단계 - 2 : Local Optimizations
로컬 최적화는 고전적인 컴파일러의 기능을 수행하여 최적화를 한다.
[ 최적화 과정 ]
Local data flow analyses and optimizations
Register usage optimization
Simplifications of Java idioms
단계 - 3 : Control Flow Optimizations
메서드 내부의 흐름을 분석하고, 코드를 재 정렬한다.
[ 흐름 제어 과정 ]
코드 재정렬, 분할 및 제거
루프 감소 및 반전
루프 스트라이딩 및 루프 불변 코드 모션
루프 풀기 및 필링
루프 버전 관리 및 전문화
예외 지향 최적화
스위치 분석
단계 - 4 : Global Optimizations
전체 메서드를 대상으로 수행된다. 컴파일 시간이 길어 비용이 크지만
성능을 크게 향상시킬 수 있는 과정이다.
[ 전역 최적화 과정 ]
글로벌 데이터 흐름 분석 및 최적화
부분적 중복 제거
탈출 분석
GC 및 메모리 할당 최적화
동기화 최적화
단계 - 5 : Native Code Generation
기계어 생성
참고
https://www.ibm.com/docs/en/ztpf/1.1.0.15?topic=reference-jit-compiler