generated from Learning-Is-Vital-In-Development/study-template
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
자바 최적화 9장 - 자바의 GraalVM과 AOT 네이티브 이미지 분석 (#23)
- Loading branch information
Showing
1 changed file
with
82 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
### JIT Compiler의 문제점 | ||
|
||
JIT Compiler는 HotSpot VM의 C2 컴파일러를 사용해서 코드 캐시를 사용한 최적화를 제공했다. | ||
C2 컴파일러는 C++을 코드 베이스로 작성이 됐고, 발전 기간이 오래된 만큼 매우 복잡한 구조를 가지고 있다. | ||
|
||
더이상 최적화를 할 수 있는 부분이 존재하지 않고, 유지보수가 어렵다고 판단되는 가운데 대안으로 등장한게 GraalVM이다. | ||
|
||
<img width="497" alt="스크린샷 2024-02-14 오후 6 12 12" src="https://github.com/CMC11th-Melly/Melly_Server/assets/82302520/01380c9c-6bdd-46e5-8923-3c7692419f0a"> | ||
|
||
- **Graal Compiler** | ||
- 기존의 C++ 기반의 C2 컴파일러를 **Java 기반**의 Graal JIT 컴파일러로 대체 | ||
- C2 Compiler 보다 발전된 성능을 보여주고, 유지보수에 유리하다 | ||
- **JVMCI** (Java Virtual Machine Compiler Interface) | ||
- C++ 베이스의 HotSpotVM 전체를 Java로 마이그레이션 하는건 불가능이라고 판단 | ||
- C2 Compiler 부분만 Java 기반의 Graal JIT Compiler로 변경하기 위해 JVMCI라는 컴파일러 인터페이스 도입 (C++ 코드 위에서 Java 컴파일러 사용 가능) | ||
- JVMCI 위에서 Graal JIT Compiler를 플러그인 형태로 사용할 수 있다. | ||
|
||
<img width="382" alt="스크린샷 2024-02-14 오후 6 49 34" src="https://github.com/CMC11th-Melly/Melly_Server/assets/82302520/0e4e1ad8-e82f-47c4-a91d-bdb0a61efa20"> | ||
|
||
- **Truffle** | ||
- GraalVM은 JVM 기반 언어(Java, Kotlin..) 이외의 언어도 JVM 위에서 동작할 수 있도록 하기 위해 Truffle이라는 Language Implementation 프레임워크를 제공 | ||
- 하나의 JVM 위에서 여러가지 언어를 동시에 실행시킬 수 있다. | ||
|
||
### GraalVM 21버전 구조 | ||
|
||
<img width="679" alt="스크린샷 2024-02-14 오후 7 04 23" src="https://github.com/CMC11th-Melly/Melly_Server/assets/82302520/1bc2585d-3607-451e-8a2d-9202638cd5a3"> | ||
|
||
기존에는 JVM 기반의 언어들은 GraalVM JIT Compiler 위에서 동작함. 21버전 부터는 JVM 기반 언어들도 Truffle Framework 위로 올리게 된다. Java on Truffle로 올라가는 JVM은 **Java 언어로 구성**되어 있다. | ||
|
||
### **Java on Truffle 방식의 장점** | ||
|
||
- JVM을 네이티브 이미지로 컴파일 가능 (JVM 자체도 Java 어플리케이션이기 때문이다) | ||
- JVM 코드가 개발자들에게 친숙하기 때문에, 추가 개발이 용이하다 | ||
- JVM 자체가 하나의 Java 어플리케이션이라서 여러 JVM을 JVM 위에서 실행 가능하다 | ||
- JVM과 Java 어플리케이션, JIT 컴파일러 모두 Java로 구성이 되기 때문에, AOT로 구성된 네이티브 이미지와 JIT 컴파일러를 함께 사용할 수 있다. | ||
|
||
|
||
<img width="627" alt="스크린샷 2024-02-14 오후 7 11 09" src="https://github.com/CMC11th-Melly/Melly_Server/assets/82302520/c3a57b55-2462-419c-b1f6-fbc2800d469e"> | ||
|
||
## GraalVM 네이티브 이미지 | ||
|
||
--- | ||
|
||
네이티브 이미지는 자바 코드를 바이너리, 즉 네이티브 실행 파일로 ahead-of-time(AoT) 컴파일하는 기술이다. | ||
|
||
네이티브 실행 파일에는 런타임에 필요한 코드(애플리케이션 클래스, 표준 라이브러리 클래스, 언어 런타임, JDK에서 정적으로 링크된 네이티브 코드)만 포함된다. | ||
|
||
### 네이티브 이미지의 특징 | ||
|
||
- 빠른 실행, 적은 용량, 낮은 메모리 사용 | ||
- 워밍업 없이 즉각적으로 최고 성능을 제공 | ||
- 빠르고 효율적인 배포를 위해 경량 컨테이너 이미지로 패키징 가능 | ||
|
||
### 컴파일러 간 성능 비교 | ||
|
||
<img width="1139" alt="스크린샷 2024-02-14 오후 7 39 19" src="https://github.com/CMC11th-Melly/Melly_Server/assets/82302520/4b1c67ea-8ce2-4a6f-94a1-a112631f1a97"> | ||
|
||
|
||
### Microservice Framework 간 성능 | ||
|
||
<img width="1104" alt="스크린샷 2024-02-14 오후 7 40 32" src="https://github.com/CMC11th-Melly/Melly_Server/assets/82302520/5079ae7f-2f1a-4bd7-ab01-6f1972a76291"> | ||
|
||
### 네이티브 이미지의 메모리 관리 | ||
|
||
네이티브 이미지는 GraalVM과 함께 제공되는 런타임 시스템을 사용한다. 네이티브 이미지 또한 객체를 자바 힙에 할당하고, GraalVM의 런타임 시스템은 GC를 통해 메모리를 관리한다. | ||
|
||
GraalVM의 Native Image는 에디션에 따라 사용할 수 있는 GC가 다르다. | ||
|
||
- **커뮤니티 에디션**을 사용할 경우 **Serial GC**만 사용 가능하다. | ||
- **엔터프라이즈 에디션**을 사용할 경우 **G1 GC**를 사용 가능하다. | ||
|
||
### AOT 네이티브 이미지 사용 사례 | ||
|
||
[넷마블 사례](https://netmarble.engineering/spring-boot-3-0-native-image-on-kubernetes/) | ||
|
||
**요약** | ||
|
||
- 쿠버네티스 환경에서 신규 파드들의 준비 시간이 길어서 각종 문제들이 발생 (클라이언트 통신 연결 대기 시간을 초과해서 누락되는 데이터 발생 등) | ||
- Native Image를 적용해서 서버 준비 시간을 **50초에서 2초로 단축** | ||
- 신규 파드를 추가할 때 사용하는 도커 이미지 크기를 기존 **JAR 기반 300MB에서 Native Image 적용 후 70MB로 축소** | ||
- AoT와 JIT 방식을 비교했을때 초반에는 AoT가 압도적으로 우세. 하지만 동작 시간이 길어질수록 JIT 컴파일러의 **최적화**와 **캐시**로 인해 **둘의 차이가 없어진다**. | ||
- **파드 증설이 빈번**하고 **초기 응답을 위한 로딩 시간을 줄이는게 중요**하다면 네이티브 이미지 적극 고려해보기 |