GraalVM은 Oracle이 개발한 고성능 JVM 및 네이티브 실행 환경으로, 기존 JVM 대비 더 빠른 실행 속도, 낮은 메모리 사용량, 다중 언어 지원을 제공하는 게 특징이다. 특히, Scala(SBT)와 Rust를 함께 사용하려면 GraalVM을 활용하여 빌드 속도를 크게 개선할 수 있다.
| GraalVM 버전 | 호환되는 JDK 버전 |
|---|---|
| GraalVM 11 | JDK 11 (LTS) |
| GraalVM 17 | JDK 17 (LTS) |
| GraalVM 21 | JDK 21 |
wget https://download.java.net/openjdk/jdk17/ri/openjdk-17+35_linux-x64_bin.tar.gz
tar -xvzf openjdk-17+35_linux-x64_bin.tar.gz
sudo mv jdk-17 /opt/openjdk17
echo 'export JAVA_HOME=/opt/openjdk17' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
vagrant@slave1:~$ java --version
openjdk 17 2021-09-14
OpenJDK Runtime Environment (build 17+35-2724)
OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
GraalVM 21 버전에서는 gu(GraalVM Updater) 도구가 기본적으로 포함되지 않으며, native-image도 자동으로 설치되지 않는다.
이러한 경우, native-image를 수동으로 설치해야 한다. 그러나, GraalVM 21 버전은 현재 사용 중인 운영 체제와의 호환성 문제로 인해 일부 기능이 제한될 수 있다.
따라서, 안정적인 설치 및 사용을 위해 GraalVM 17 버전으로 권장한다. GraalVM 17은 LTS(Long-Term Support) 버전으로, gu 도구와 native-image가 기본적으로 포함되어 있어 설치 및 사용이 용이하다.
wget https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-17.0.9/graalvm-community-jdk-17.0.9_linux-x64_bin.tar.gz
tar -xvzf graalvm-community-jdk-17.0.9_linux-x64_bin.tar.gz
sudo mv graalvm-community-openjdk-17.0.9+9.1 /opt/graalvm
export PATH="/opt/graalvm/bin:$PATH"
export JAVA_HOME="/opt/graalvm"
echo 'export PATH="/opt/graalvm/bin:$PATH"' >> ~/.bashrc
echo 'export JAVA_HOME="/opt/graalvm"' >> ~/.bashrc
source ~/.bashrc
버전 확인 시 아래 처럼 GraalVM CE 17.0.9+9.1 문구가 올라와야 한다.
vagrant@slave1:~$ java --version
openjdk 17.0.9 2023-10-17
OpenJDK Runtime Environment GraalVM CE 17.0.9+9.1 (build 17.0.9+9-jvmci-23.0-b22)
OpenJDK 64-Bit Server VM GraalVM CE 17.0.9+9.1 (build 17.0.9+9-jvmci-23.0-b22, mixed mode, sharing)
"Native Image" 기능을 사용하면 JVM 없이 실행 파일을 생성 가능하다.
하지만 아래 사항의 문제점이 있으니 참고하자.
JVM 기반 대규모 엔터프라이즈 애플리케이션에서 활용이 힘들 수 있다.
public class Benchmark {
public static void main(String[] args) {
long start = System.nanoTime();
int count = countPrimes(50_000);
long end = System.nanoTime();
System.out.println("Prime Count: " + count);
System.out.println("Execution Time: " + (end - start) / 1e6 + " ms");
}
private static int countPrimes(int limit) {
int count = 0;
for (int i = 2; i <= limit; i++) {
if (isPrime(i)) {
count++;
}
}
return count;
}
private static boolean isPrime(int num) {
if (num < 2) return false;
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) return false;
}
return true;
}
}
sudo apt update
sudo apt install build-essential
gcc --version
sudo apt update
sudo apt install zlib1g-dev
Native Image만드는 시간이 많이 든다.
vagrant@slave1:~$ native-image Benchmark
========================================================================================================================
GraalVM Native Image: Generating 'benchmark' (executable)...
========================================================================================================================
Warning: The host machine does not support all features of 'x86-64-v3'. Falling back to '-march=compatibility' for best compatibility.
[1/8] Initializing... (5.6s @ 0.08GB)
Java version: 17.0.9+9, vendor version: GraalVM CE 17.0.9+9.1
Graal compiler: optimization level: 2, target machine: compatibility
C compiler: gcc (linux, x86_64, 9.4.0)
Garbage collector: Serial GC (max heap size: 80% of RAM)
[2/8] Performing analysis... [****] (21.5s @ 0.30GB)
2,908 (71.64%) of 4,059 types reachable
3,529 (51.03%) of 6,915 fields reachable
13,179 (43.69%) of 30,164 methods reachable
906 types, 0 fields, and 348 methods registered for reflection
58 types, 58 fields, and 52 methods registered for JNI access
4 native libraries: dl, pthread, rt, z
[3/8] Building universe... (2.9s @ 0.34GB)
[4/8] Parsing methods... [**] (2.5s @ 0.29GB)
[5/8] Inlining methods... [***] (1.4s @ 0.29GB)
[6/8] Compiling methods... [****] (19.2s @ 0.30GB)
[7/8] Layouting methods... [*] (1.0s @ 0.45GB)
[8/8] Creating image... [[8/8] Creating image... [*]
(1.5s @ 0.31GB)
4.38MB (36.55%) for code area: 7,486 compilation units
7.03MB (58.63%) for image heap: 89,135 objects and 5 resources
592.55kB ( 4.83%) for other data
11.99MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 origins of code area: Top 10 object types in image heap:
3.35MB java.base 1006.82kB byte[] for code metadata
770.68kB svm.jar (Native Image) 888.03kB java.lang.String
111.98kB java.logging 835.41kB byte[] for general heap data
61.92kB org.graalvm.nativeimage.base 671.02kB java.lang.Class
23.82kB jdk.internal.vm.ci 664.54kB byte[] for java.lang.String
23.10kB org.graalvm.sdk 347.30kB java.util.HashMap$Node
6.10kB jdk.internal.vm.compiler 249.91kB com.oracle.svm.core.hub.DynamicHubCompanion
1.94kB Benchmark 168.67kB java.lang.String[]
1.35kB jdk.proxy1 165.57kB java.lang.Object[]
1.27kB jdk.proxy3 148.84kB byte[] for embedded resources
1.56kB for 2 more packages 1.19MB for 825 more object types
Warning: The host machine does not support all features of 'x86-64-v3'. Falling back to '-march=compatibility' for best compatibility.
------------------------------------------------------------------------------------------------------------------------
Recommendations:
HEAP: Set max heap for improved and more predictable memory usage.
CPU: Enable more CPU features with '-march=native' for improved performance.
------------------------------------------------------------------------------------------------------------------------
4.3s (7.5% of total time) in 90 GCs | Peak RSS: 1.05GB | CPU load: 1.89
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
/home/vagrant/benchmark (executable)
========================================================================================================================
Finished generating 'benchmark' in 56.3s.
vagrant@slave1:~$ time java Benchmark
Prime Count: 5133
Execution Time: 3.674163 ms
real 0m0.097s
user 0m0.032s
sys 0m0.111s
vagrant@slave1:~$ time ./benchmark
Prime Count: 5133
Execution Time: 1.502573 ms
real 0m0.006s
user 0m0.007s
sys 0m0.000s