JIT(Just-In-Time) 컴파일러는 프로그램 실행 중에 바이트코드(Bytecode)를 기계어(Machine Code)로 동적으로 변환하여 프로그램을 실행하는 컴파일러.
: 동적으로 변환한다는 것은 JIT 컴파일러는 프로그램 실행 시점(runtime)에 코드의 실행 흐름을 분석. 또 모든 코드를 미리 컴파일하는 것이 아니라, 실제로 실행되는 코드만 동적으로 변환 -> 초기 실행 시간이 단축되고, 메모리를 효율적으로 사용.
주로 Java와 같은 가상 머신(JVM) 기반의 언어에서 사용되며, 프로그램의 실행 속도를 크게 향상시킬 수 있습니다.
JIT 컴파일러의 특징
동작 과정
1. JVM이 .class 형태의 바이트코드를 메모리에 로드
2. 초기에는 인터프리터가 바이트코드를 한 줄씩 읽어 실행
3. JVM이 런타임 동안 자주 실행되는 코드(핫스팟)을 감지
4. 핫스팟 코드를 기계어로 변환하고 최적화 수행
5. 변환된 기계어 코드를 실행하여 성능을 향상
-XX:+PrintCompilation을 사용하여 JIT 컴파일 과정을 확인.예제 코드 (Spring 없이 기본 Java):
public class JITExample {
public static void main(String[] args) {
for (int i = 0; i < 100000; i++) {
System.out.println(process(i));
}
}
public static int process(int x) {
return x * x;
}
}
실행 명령:
java -XX:+PrintCompilation JITExample
결과:
process 메서드가 반복 호출되면서 JIT에 의해 컴파일됨.예제 코드:
@RestController
@RequestMapping("/api")
public class JITController {
@GetMapping("/compute")
public int compute() {
int result = 0;
for (int i = 0; i < 100000; i++) {
result += i * i;
}
return result;
}
}
실행:
1. Spring Boot 애플리케이션 실행.
2. curl 또는 Postman으로 /api/compute 엔드포인트를 반복 호출.
curl http://localhost:8080/api/compute
java -XX:+PrintCompilation -jar target/your-app.jar결과:
compute 메서드가 JIT에 의해 컴파일되어 실행 속도가 점점 빨라짐.실행 명령:
1. JIT 비활성화:
java -Xint -jar target/your-app.jar
-Xint: 순수 인터프리터 모드(인터프리터만 사용, JIT 사용 안 함).java -jar target/your-app.jar결과:
실행 방법:
1. Spring Boot 애플리케이션 실행.
2. VisualVM 설치 후 애플리케이션 프로세스 선택.
3. Heap 메모리와 클래스 로딩 데이터를 분석.
4. JIT 활성화 상태에서 캐싱된 기계어 코드와 관련된 메모리 증가 확인.
Java와 Spring 개발자로서 JIT 컴파일러를 이해하고 관련 실습을 진행하면 JVM 기반 애플리케이션 성능 최적화에 대한 깊은 통찰을 얻을 수 있습니다. 특히, Spring 애플리케이션의 서비스 메서드, REST API, 반복 로직에서 JIT 최적화의 효과를 체험하며, 이를 통해 JVM 성능 튜닝의 기반 지식을 쌓을 수 있습니다.