Graalvm 替代 JVM 真的可以带来巨大的性能优势吗?

介绍Spring Boot有助于轻松开发独立的、可用于生产的 Spring 应用程序 。它对 Spring 平台和第三方库采用固执己见的方法:以最少的配置简化设置过程 。优势:

  • 易于使用:Spring Boot 简化了独立 Spring 应用程序的创建 , 无需复杂的配置 。
  • 嵌入式服务器:它允许直接嵌入 Tomcat、Jetty 或 Undertow 等服务器,从而无需单独部署 WAR 文件 。
  • Starter 依赖项:Spring Boot 提供预配置的“starter”依赖项,降低了构建配置的复杂性 。
  • 自动配置:Spring Boot 自动配置 Spring 和第三方库,最大限度地减少手动设置工作 。
  • 生产就绪功能:它提供生产就绪功能,例如指标、运行状况检查和外部化配置,确保应用程序稳健且可扩展 。
  • 无需代码生成或 XML 配置:Spring Boot 运行时无需生成任何代码,无需 XML 配置文件,从而提高了开发效率 。
在常见的部署中,用 JAVA 编写的 Spring Boot 应用程序被编译成默认在 Java 虚拟机 (JVM) 中运行的字节码 。还有另一种鲜为人知的运行 Java 应用程序的方式:Native Application
GraalVM通过提前将 Java 应用程序编译成紧凑的独立二进制文件,彻底改变了 Java 应用程序 。这些二进制文件展现出明显的优势,启动速度比传统 Java 应用程序快近 100 倍 。它们无需预热即可提供峰值性能 , 同时与 Java 虚拟机 (JVM) 同类产品相比,消耗的内存和 CPU 资源显着减少 。
GraalVM 并不局限于理论创新领域;它受到 Spring Boot、Micronaut、Helidon 和 Quarkus 等主要微服务框架的支持 。此外,Oracle Cloud Infrastructure、Amazon Web Services、google Cloud Platform 和 Microsoft Azure 等领先的云平台完全支持 GraalVM 集成 。
通过利用配置文件引导的优化和先进的 G1(垃圾优先)垃圾收集器,GraalVM 使我们的应用程序具有更低的延迟 。事实上,它提供的性能指标与在 Java 虚拟机 (JVM) 上运行的应用程序的性能指标相当或更强 。这种速度、效率和安全性的卓越结合使 GraalVM 成为现代 Java 开发的改变游戏规则的选择 。
过去,有很多使用 GraalVM 对 Java 应用程序进行基准测试的请求,期望 GraalVM 能够超越传统的 Java 虚拟机 (JVM) 。
在本篇文章中,我们将对各种 Java 应用程序的性能进行比较分析 , 评估它们在 JVM 和 GraalVM 环境中的执行情况 。
我们将通过在 JVM(Java 虚拟机)和 GraalVM 上执行基本的“hello world”应用程序进行比较分析 。通过这个比较,我们旨在探索 GraalVM 相对于传统 JVM 的优越性能 。
测试设置所有测试均在具有 16G RAM 的 macBook M1 上执行 。软件版本有:
  • JDK 21
  • Graalvm JDK 21
  • SpringBoot 3.1.4
应用程序代码是一个包含单个路由的简单文件:
package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.http.ResponseEntity;import org.springframework.http.HttpStatus;import org.springframework.web.bind.annotation.RestController;@SpringBootApplication@RestControllerpublic class DemoApplication {public static void mAIn(String[] args) {SpringApplication.run(DemoApplication.class, args);}@GetMapping("/")public String handleRequest() {return "Hello World!";}}为了构建原生镜像,我们使用了 MVN 的原生插件:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.4</version><relativePath/><!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties><java.version>21</java.version> </properties> <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency> </dependencies> <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass>com.example.demo.DemoApplication</mainClass><layout>JAR</layout></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.5.0</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals></execution></executions></plugin></plugins> </build> <profiles><profile><id>native</id><build><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><version>0.9.27</version><extensions>true</extensions><executions><execution><id>build-native</id><goals><goal>compile-no-fork</goal></goals><phase>package</phase></execution><execution><id>test-native</id><goals><goal>test</goal></goals><phase>test</phase></execution></executions><configuration><!-- ... --></configuration></plugin></plugins></build></profile> </profiles></project>


推荐阅读