• JIT compiler & GraalVM in java
    DEV 2023. 12. 3. 09:28

    build & compile

    자바 성능향상을 위한 시도들. JIT compiler부터 GraalVM까지

    JIT(Just-In-Time) Compiler

    • JVM의 일부, 자바를 고성능으로 만드는데 큰 역할

     

    JIT complier

    • java는 byte code로 컴파일, 컴파일 한 byte code를 JVM이 런타임시 native code로 변환하여 실행
    • 처음에는 인터프린터 방식으로 바이트 코드 실행
    • 인터프린터 사용 → 초기 실행 속도는 빠를 수 있지만, 컴파일러 보다 성능 ⬇️
    • JIT compiler 두 가지 방식을 모두 사용

     

    c1, c2 compiler

    • JVM에서 처음 호출되자마자 컴파일되는 것은 아니고, 메서드 호출마다 횟수를 기록, 특정 수치를 초과하면 컴파일(warm up → C1, C2 컴파일 이후)
    • C1, C2 컴파일러 C++로 작성
    • C1: 초기 실행 속도에 중점, 빨리 코드를 최적화 컴파일
    • C2: 실행 중 성능에 중점, 오랜 시간 코드를 분석 더 나은 최적화
    • 인터프린터, 컴파일러의 장점을 모두 사용한다고 했지만, 자바의 구조적인 이슈 때문에 시작속도가 늦다. → warm up이 필요

     

    JIT compile process

    구조적인 이슈?

    • JVM
      - 자바 이전의 모든 컴퓨터 프로그램은 OS에 맞게 작성, 메모리 관리 → 개발자
      - write once, run anywhere
    • 물리머신 ← JDK, tomcat, apache,,, 커멘드라인으로 설치
    • docker(container) JDK의 위치가 애매..
      - docker에서 base image 설정 가능 → 굳이 JVM 써야 하는가?

    GraalVM

    • Java Runtime
    • Oracle Java, Open JDK 확장한 오라클이 만들고 있는 차세대 자바
    • Licence
      - Community edition → Open JDK 확장 → free
         - 기존 Oracle Java 보다 15% 성능 ☝🏻
      - Enterprise edition → Oracle Java 확장 → Oracle Java Licence
         - GraalVM Community endition 보다 10% 성능 👆🏻

    Spring Native

    • Spring Native documentation
    • GraalVM Native Image 컴파일러를 사용 → 네이티브 실행 파일로 컴파일 지원
      - .java → compile → .class → JVM → native code ❌
      - .java → compile → 실행파일 → GraalVM 👌🏻
    • SpringBoot 3.0에서 공식 지원

    GraalVM 목표

    GraalVM

    1. 성능 개선 - JIT Compiler - Graal

    GraalVM compiler

    • 현재까지 만들어진 JIT compiler의 성능향상이 어렵다고 판단
    • C2 컴파일러를 Java로 구현 → Graal
      - Graal: 고성능 JIT 컴파일러
    • 기존 C++로 작성한 C2보다 코드 최적화 성능 ☝🏻
    • JDK를 GraalVM으로 변경하는 것만으로도 성능향상 효과
    • app 구동시간이 단축되는 것이 아니고, 기존 C2의 성능 향상
      - warm up이후 성능향상

    warm up

    • 기존 프로젝트를 GraalVM으로만 변경하여 JIT모드로 돌려도
      →  sprinng initialize 시간은 변함이 없었다.
      → 기존 JIT 컴파일러에서 C2 컴파일러 부분만 변경되었기 때문에 변함이 없는 건 당연함
      → 기존 JVM과 GraalVM의 성능테스트를 비교한다면 C2컴파일러 부분의 최적화가 GraalVM에서 더 잘 이루어졌기 때문에
      → peek throuput, latency에서 더 좋은 성능을 관찰할 수 있을 듯

    • JVMCI는 JDK 9부터 OpenJDK의 일부
      - XX:+UnlockExperimentalVMOptions
      -XX:+EnableJVMCI -XX:+UseJVMCICompiler

    왜 자바로 작성했더니 더 빨라졌는가?

    • Understanding How Graal Works - a Java JIT Compiler Written in Java
    • C2는 C++로 작성 → 본질적으로 문제는 없지만, C++의 오류로 VM이 충돌할 수 있다.
      → 아마도 코드의 나이 때문(유지관리, 확장) → 개발이 너무 어려워서..
    • 컴파일러가 하는 일은 프로그램을 사용하고 조작하는 것 → 이렇게 하려면 일종의 데이터 구조를 사용해 프로그램을 나타내야 함 → Graal은 그래프를 사용해 프로그램을 나타냄

    program -> data sturcture
    program -> data sturcture

    int average(int[] values) {
    
      int sum = 0;
    
      for (int n = 0; n < values.length; n++) {
    
        sum += values[n];
    
      }
    
      return sum / values.length;
    
    }
    • 기존 C2도 유사한 데이터 구조를 사용했기 때문에 Graal이 혁신이라고 할 수 없지만 데이터 구조를 최적화하고 컴파일할 때 JAVA의 이점은 그래프 구조가 객체지향 언어와 완벽하게 호환되기 때문

    2. 네이티브 이미지 컴파일 → AOT(Ahead of Time)

    • 사전 컴파일
    • JIT에서 하는 작업들을 최소화하자.

    JIT, AOT

    • 자바 class파일을 실행 파일로 만들 수 있는 컴파일러
    • 실행파일만 만들고 docker container에서 실행 → 컨테이너 사이즈 🔽
    • 초기 실행 속도 ⬆️
    • 단점 : 네이티브 이미지를 만드는 컴파일 시간이 길다

    CPU, Memory usage

    • AOT가 JIT의 상위 호환 같지만 아직은 특징이 다르다

    AOT, JIT

    • 오랫동안 고성능으로 운영돼야 하는 app → JIT
    • 빠르게 실행하고 빠르게 종료해야 하는 app → AOT
      - AOT의 Throghput, Latency가 JIT보다 낮은 이유
      → JIT 컴파일러에서 환경, 상황에 맞는 머신코드가 만들어져 실행되기 때문

    GraalVM AOT의 최종 목표

    GraalVM AOT

    How Throughput, Latency?

    JIT 컴파일

    • 인터프린터가 만든 프로파일 정보를 이용, 상황에 맞는 profile정보 생성
      → 프로파일 정보가 안정화 → warm up이 완료
    • AOT 컴파일 시 profile 정보를 가지고 있다면 JIT모드처럼 코드 최적화를 할 수 있고 생성되는 머신코드가 더 좋아지지 않을까?

    Entierprise edition 성능이 더 좋은 이유

    • AOT 컴파일 시 profile을 넣어주는 옵션은 Enterprise edition만 제공
    • JIT 컴파일러도 최적화 알고리즘이 Enterprise edition에 25% 정도 더 많다.

    GraalVM Native image(AOT), GraalVM JIT, JDK12

    performance GraalVM AOT, GraalVM JIT, JDK12

    • Native image(AOT)는 실행 초기부터 높은 throuput을 제공
    • JIT은 실행 초기 부터 warm up 되면서 c2 compile이후 기존 JDK, AOT보다 15% 정도 높은 처리량을 보여준다.

    AOT mode, JIT mode

    Reference

    728x90

    'DEV' 카테고리의 다른 글

    Virtual Thread & Structured Concurrency & Coroutine  (0) 2023.12.03
    LangChain에 대하여  (1) 2023.12.03
    Spring batch jobScope, stepScope  (0) 2023.12.02
    Elasticsearch에서의 relation  (1) 2023.12.02
    Spring batch integration test (feat.Elasticsearch)  (0) 2023.12.02
go.