GraalVM与Spring Native初体验,一个让你的应用在100ms内启动的神器
先吹一波截图,当中springboot的启动只用了0.036秒,试问如果没有Spring Native,谁还能做到。
即使是M1 Mac Pro启动也是需要0.559 秒。两张图片的时间差距比较久是因为在写博客的时候,突发奇想想把solo博客也给做成GraalVM的,但是很可惜失败了,这里省略几百字的小作文,但是会提到为什么失败了。

1. 一些背景知识
1.1 GraalVM
GraalVM在官方网站对自己的介绍是 High Performanсe. Cloud Native. Polyglot 意思就是 高性能,云原生,多语言。
GraalVM for Java 具有新的编译器优化的高性能runtime,以加速Java应用程序性能和较低的基础设施成本以及云中的基础设施成本。Graalvm是Java和其他JVM语言的高性能runtime。它包含一个兼容的JDK,并提供基于Java 8(仅GRAALVM Enterprise Edition),Java 11和Java 17 Graalvm提供多个编译器优化的分布,旨在加速Java应用程序性能,同时消耗更少的资源。要开始使用Graalvm,或从另一个JDK分发迁移,您不必更改任何源代码。在Java Hotspot VM上运行的任何应用程序将在Graalvm上运行。
很官方啊,这样的话。说的明白点就是GraalVM是一个共享运行时间的生态系统,无论是那些依赖于JVM的语言(Java、Scala、Groovy、Kotlin)还是说其他的编程语言例如(JavaScript、Ruby、Python、R)有性能上的优势。另外,GraalVM能够通过一种前端的LLVM执行JVM上面的原生代码。
2. 安装GraalVM
这里会说到Windows, Mac,linux下的安装过程。
2.1 下载
找到你电脑安装的Jdk的版本进行下载

这里推荐安装Java11,Java17的版本我安装之后发现有问题,在我改成Java11后没有修改其他配置的情况下却又成功了。
2.2 安装
linux and mac
这里linux和mac下一起讲是因为差不多,会其中一个,另一个你也可以延展的去安装。
下载解压后,放在和你的JDK同一级目录下,如:
tar -xzf <graalvm-archive>.tar.gz

更改环境变量
linux,以centos为例就是更改 /etc/profile 文件,macOS下就是更改 ~/.zshrc文件,在这里需要把你之前安装的JDK时配置的 JAVA_HOME进行修改为:GraalVM的地址
export JAVA_HOME=/Users/asher/workspace/software/jdk/graalvm-ce-java11-21.3.0/Contents/Home
然后在PATH路径进行添加
export PATH=$PATH:$MAVEN_HOME/bin:$FFMPEG_HOME/bin:/Users/asher/workspace/software/jdk/graalvm-ce-java11-21.3.0/Contents/Home/bin:$JAVA_HOME:.
注意,我在上面添加了 /Users/asher/workspace/software/jdk/graalvm-ce-java11-21.3.0/Contents/Home/bin的路径,这个是需要进行添加的
centos下别忘了 source /etc/profile
Windows
解压下载的文件
然后win+R打开你的命令行
setx /M JAVA_HOME "C:\Progra~1\Java\<graalvm>"
配置环境变量
setx /M PATH "C:\Progra~1\Java\<graalvm>\bin;%PATH%"
当你安装配置完成之后,打开新的命令行窗口,执行 java -version
就会发现JDK已经改成了新安装的那个了,类似如下截图

3. 从Hello World开始
已经安装完成之后,我们从最简单的Hello World开始,体会一下GraalVM和JVM的区别
新建一个Java文件,HelloWorld.java
然后输入
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
3.1 JVM版
我们需要 javac HelloWorld.java, 然后 java HelloWorld ,我们用记录一下
java HelloWorld 所需要的时间
总计0.077秒
3.2 GraalVM版
先进行安装 native-image
gu install native-image
然后在刚刚编 译HelloWorld的目录下进行执行
native-image HelloWorld
等待一段时间,此时会直接生成一个可执行文件

等待一段时间后,我们会发现文件生成了

让我们执行看看

完全没问题,再测试一下时间呢

0.063秒!拿出之前和JVM执行的对比一下,它在执行的时候,用户态和系统态使用的时间都低 于JVM

虽说GraalVM确实快了,但是你也注意到了,当执行的 native-image HelloWorld时候会有好几个阶段,而且都很耗时间跟内存。
4. 进阶版, Maven 插件编译
看完了上面的,你可能觉得差距不大,毕竟这几微秒的事,咱们都体会不出来。
这里会说到的是在我们常见的Maven项目如何进行使用GraalVM。
让我们新建一个Maven项目, 整个程序的目录结构是这样的,只有一个 Application.java 和一个 Person.java文件

4.1 pom.xml
因为这里我们要使用maven plugin进行打包,加入了 dependency graal-sdk ,然后引入了 native-image-maven-plugin
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<graal-sdk.version>21.3.0</graal-sdk.version>
</properties>
<dependencies>
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>${graal-sdk.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>21.2.0</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<skip>false</skip>
<imageName>graalvmMaven</imageName>
<mainClass>run.runnable.Application</mainClass>
<buildArgs>
--no-fallback
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
然后的话我们还需要在IDEA中进行配置编译的Java版本是下载的GraalVM下的Java
