Author | Leng Leng
Source | https://mp.weixin.qq.com/s/0m6ofmMlQTDUQwC7oRRIrQ
GraalVM [1] is a high-performance virtual machine, which can significantly improve the performance and operating efficiency of the program, very suitable for microservices . The recently popular Java framework Quarkus [2] supports GraalVM by default
The figure below shows the comparison between Quarkus and the traditional framework (SpringBoot), which has faster startup data, smaller memory consumption, and shorter service response .
Spring Boot 2.4 began to gradually provide support for GraalVM, aiming to improve the startup, memory, and response experience described above .
Install GraalVM
The latest official community version is 20.3.0, which is customized based on OpenJDK 8u272 and 11.0.9, which can be understood as a derivative version of OpenJDK.
The official recommendation is SDKMAN [3] which is used to quickly install and switch between different versions of JDK, similar to nodejs' nvm [4].
Use similar commands to complete the specified version installation and specify the default version
sdk install java 11.0.9.hs-adpt
sdk default java 11.0.9.hs-adpt
However, during the installation process, you need to download related resources from abroad. The author's experience is not very good after trying it. It is recommended that you download the specified version of GraalVM and install it (the same way as JDK installation).
Successful installation view version
⋊> ~ java -version 11:30:34
openjdk version "11.0.9" 2020-10-20
OpenJDK Runtime Environment GraalVM CE 20.3.0 (build 11.0.9+10-jvmci-20.3-b06)
OpenJDK 64-Bit Server VM GraalVM CE 20.3.0 (build 11.0.9+10-jvmci-20.3-b06, mixed mode, sharing)
Install native-image
Native-image is an AOT compiler developed by Oracle Labs. The required class dependencies and runtime library are packaged and compiled to generate a single executable file. It has the advantages of efficient startup and small runtime memory overhead .
However, GraalVM is not built-in but only provides the gu installation tool, which requires us to install it separately.
- 切换到 jdk 的安装目录
⋊> ~ cd $JAVA_HOME/bin/
- 使用gu命令安装
⋊> ./gu install native-image
Initialize the Spring Boot 2.4 project
Spring Initializr creates a demo project
curl https://start.spring.io/starter.zip -d dependencies=web \
-d bootVersion=2.4.1 -o graal-demo.zip
Let’s take a look at the start-up benchmark data. It takes 1135 ms to simply run an empty project.
java -jar demo-0.0.1-SNAPSHOT.jar
engine: [Apache Tomcat/9.0.41]
2020-12-18 11:48:36.856 INFO 91457 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-12-18 11:48:36.856 INFO 91457 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1135 ms
Memory usage
ps aux | grep demo-0.0.1-SNAPSHOT.jar | grep -v grep | awk '{print $11 "\t" $6/1024"MB" }'
/usr/bin/java 480.965MB
Support GraalVM
Increase related dependencies, involving more plug-ins. Completely uploaded Gitee Gist [5]
<!-- 新增的部分,注意需要增加 spring maven 仓库地址才能下载到-->
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-graalvm-native</artifactId>
<version>0.8.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
</dependency>
<!--需要添加 spring maven 仓库下载 spring-graalvm-native-->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
Main method modification, proxyBeanMethods = false
@SpringBootApplication(proxyBeanMethods = false)
Use native-image to build executable files
mvn -Pnative package
#构建过程比较慢,日志如下
spring.factories files...
[com.example.demo.demoapplication:93430] classlist: 4,633.58 ms, 1.18 GB
_____ _ _ __ __ _
/ ___/ ____ _____ (_) ____ ____ _ / | / / ____ _ / /_ (_) _ __ ___
\__ \ / __ \ / ___/ / / / __ \ / __ `/ / |/ / / __ `/ / __/ / / | | / / / _ \
___/ / / /_/ / / / / / / / / / / /_/ / / /| / / /_/ / / /_ / / | |/ / / __/
/____/ / .___/ /_/ /_/ /_/ /_/ \__, / /_/ |_/ \__,_/ \__/ /_/ |___/ \___/
/_/ /____/
...
[com.example.demo.demoapplication:93430] [total]: 202,974.38 ms, 4.23 GB
Compilation result
Generate an com.example.demo.demoapplication
executable file with the name in the target directory
Start the compiled executable file executed here instead of jar
cd target
./com.example.demo.demoapplication
Start-up time 0.215 seconds
2020-12-18 12:30:40.625 INFO 94578 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.215 seconds (JVM running for 0.267)
Take a look at the memory footprint of 24.8203MB
ps aux | grep com.example.demo.demoapplication | grep -v grep | awk '{print $11 "\t" $6/1024"MB" }'
./com.example.demo.demoapplication 24.8203MB
Data comparison
Whether to introduce GraalVM | Memory footprint | Start Time |
---|---|---|
no | 480.965MB | 1135 ms |
Yes | 24.8203MB | 215 ms |
Reference
[1] GraalVM: https://www.graalvm.org
[2]Quarkus: https://quarkus.io
[3]SDKMAN: https://sdkman.io/install
[4] nvm: https://github.com/creationix/nvm
[5]Gitee Gist: https://gitee.com/gi2/codes/famcqz6n21iylpg3us7j036
Friends who like this article, welcome to follow the official account programmer Xiaohui , and watch more exciting content
点个[在看],是对小灰最大的支持!