美文网首页后端java学习资料
如何把Java程序的启动速度加快100倍?GraalVM了解一下

如何把Java程序的启动速度加快100倍?GraalVM了解一下

作者: jerry的技术与思维 | 来源:发表于2020-06-14 22:39 被阅读0次

    在云原生时代,Java程序是有很大的劣势的,为什么这么说呢?你看Java的一个最简单的hello world都要大几十M的内存,启动也不不快。以最流行的spring boot/spring cloud微服务框架为例,启动一个已经优化好,很多bean需要lazy load的application至少需要3-4秒时间,内存需要几百M,业务逻辑稍微复杂一点点,没有1G以上的内存是很难满足业务的需要呢?

    那么在云原生时代,Java会落后吗?答案到现在,笔者也不好说,不过大概率不会,为什么呢?因为java社区没有闲着,弄出来很多好玩的黑科技。下面我就一个充满黑科技的JVM介绍给大家,用他能帮助我们让Java程序的启动速度加快100倍,内存只需要原来的五分之一,甚至更少。

    还等什么,让我们开始吧。

    一、Graalvm的介绍

    Graal VM是2018年Oracle开发的下一代JVM实现,被官方称为“Universal VM”和“Polyglot VM”,这是一个在HotSpot虚拟机基础上增强而成的跨语言全栈虚拟机,可以作为“任何语言”的运行平台使用,这里“任何语言”包括了Java、Scala、Groovy、Kotlin等基于Java虚拟机之上的语言,还包括了C、C++、Rust等基于LLVM的语言,同时支持其他像JavaScript、Ruby、Python和R语言等等。Graal VM可以无额外开销地混合使用这些编程语言,支持不同语言中混用对方的接口和对象,也能够支持这些语言使用已经编写好的本地库文件。

    主要特性包括:

    • 高性能的现代Java
    • 占用资源少,启动速度快
    • JavaScript, Java, Ruby以及R混合编程
    • 在JVM上运行原生语言
    • 跨语言工具
    • JVM应用扩展
    • 原生应用扩展
    • 本地Java库
    • 数据库支持多语言
    • 创建自己的语言

    二、Graalvm安装及环境配置

    GraalVM包括社区版和企业版,我们以社区版为例,截取当前2020年6月份,最新的Release版本为:Graalvm Community 20.1.0,下载地址:https://www.graalvm.org/downloads/
    不过社区版需要会让你跳转到github进行下载,github下载很慢,需要科学翻墙才行。

    2.1 在Windows 10平台上安装

    请按照以下步骤在x86 64位Windows上安装GraalVM Community Edition。

    1. GitHub上GraalVM Releases存储库。根据电脑配置,选择graalvm-ce-java8-windows-amd64-20.1.0.zipgraalvm-ce-java11-windows-amd64-20.1.0.zip并下载。

    2. 将文件压缩到文件系统,比如 d盘根目录。

    3. 配置JAVA_HOMEPATH环境变量。在Windows 7、8和10中,通过命令行设置环境变量的工作方式相同。

      • 将GraalVM bin文件夹添加到PATH环境变量:

        setx /M PATH "d:\graalvm-ce-java8-20.1.0\bin;%PATH%"
        
        
      • 设置JAVA_HOME环境变量以解析到GraalVM安装目录:

        setx /M JAVA_HOME "d:\graalvm-ce-java8-20.1.0"
        
        

        请注意/M,等同于的标志-m需要管理员权限的命令行。

    4. 重新启动命令提示符以重新加载环境变量。然后使用以下命令检查变量设置是否正确:

      echo %PATH%
      echo %JAVA_HOME%
      
      
        java -version
       openjdk version "1.8.0_252"
       OpenJDK Runtime Environment (build 1.8.0_252-b09)
       OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 25.252-b09-jvmci-20.1-b02, mixed mode)
    

    2.2 使用gu工具安装 native image

    要在GraalVM Community Edition中添加对Python,R,Ruby或WebAssembly语言解释器的支持,请使用功能[gu实用程序]GitHub上有一个由Oracle(gu available)维护的组件目录,您可以从中按名称安装组件:

    gu install ruby
    gu install r
    gu install python
    gu install wasm
    
    

    要安装LLVM工具链组件,请运行:

    gu install llvm-toolchain
    
    

    要安装GraalVM本机映像,请运行:

    gu install native-image
    
    

    在Windows上使用native images的先决条件

    要在Windows上使用本机映像,请遵循其他建议。所需的Microsoft Visual C ++(MSVC)版本取决于GraalVM所基于的JDK版本。对于基于JDK 8的GraalVM分发,您将需要MSVC 2010 SP1版本。推荐的安装方法是使用Microsoft Windows SDK 7.1:

    1. GRMSDKX_EN_DVD.isoMicrosoft下载SDK文件。
    2. 通过F:\Setup\SDKSetup.exe直接打开安装图像。

    对于基于JDK 11的GraalVM分发,您将需要MSVC 2017 15.5.5或更高版本。

    对于基于JDK 11和JDK 8的GraalVM发行版,共同的最后一个先决条件是适用于您的Visual Studio版本的正确的Developer Command Prompt。即,它应该是x64本机工具命令提示符。使用Visual Studio 2017或更高版本。

    三、spring boot之Graalvm

    其实在2019年spring 团队已经开始作手支持graalvm的native image功能。就在前几天(2020-6-10)spring-graalvm-native 发布了0.7.0版本。Spring团队承诺对Graal VM的支持必须在2020年10月之后才会正式提供,但现在的我们其实已经可以使用Graal VM来(实验性地)运行Spring、Spring Boot、Spring Data、Netty、JPA等等的一系列组件(不过SpringCloud中的组件暂时还不行)。
    接下来,我们将尝试使用Graal VM来编译一个标准的Spring Boot应用。

    3.1 准备工作

    首先,我们先假设你准备编译的代码是“符合要求”的,即没有使用到Graal VM不支持的特性,譬如前面提到的Finalizer、CGLIB、InvokeDynamic这类功能。然后,由于我们用的是Graal VM的Java 8版本,也必须假设你编译使用Java语言级别在Java 8以内。
    spring-graalvm-native的0.7版本基于刚刚发布的Spring Boot 2.3和上面提到的Graalvm 20.1.0 版本。请将你的pom.xml中的Spring Boot版本修改如下(假设你编译用的是Maven,用Gradle的请自行调整):

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0</version>
        <relativePath/>
    </parent> 
    

    同时在pom.xml中增加spring对graalvm的支持(别忘了现在也添加Spring Milestones存储库,因为现在还没有通过Maven Central发行)。):

    <dependencies>
            <dependency>
                <groupId>org.springframework.experimental</groupId>
                <artifactId>spring-graalvm-native</artifactId>
                <version>0.7.0</version>
            </dependency>
            ...
            <dependencies>
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
            </repository>
        </repositories>
        <pluginRepositories>
            <pluginRepository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
            </pluginRepository>
        </pluginRepositories>
    

    由于GraalVM不支持GCLIB代理,因此Spring Boot需要使用JDK代理。因此,请使用proxyBeanMethods = false@SpringBootApplication类的属性:

    @SpringBootApplication(proxyBeanMethods = false)
    public class SpringBootHelloApplication {
        ...
    }
    

    3.2 开始native image成本地原生程序

    现在,我们几乎已经准备好一切,最终可以运行native-image命令。这是一个示例,该示例基于提到的实现Reactive Spring Boot Web应用程序的示例项目。把java程序编译成本地程序,是一个很难一次性成功的事情,它取决于要编译为GraalVM本机映像的Spring Boot应用程序的类型!因此,最好的方法是从spring-graal-native项目的示例项目中获得一些参考和提示。

    开始吧:

    1. 先maven编译,这部很简单,我们都很熟悉
    mvn clean package
    
    1. 运行native image命令进行本地原生编译
    native-image \
      -H:+TraceClassInitialization \
      -H:Name=spring-boot-graal
      -H:+ReportExceptionStackTraces \
      -Dspring.graal.remove-unused-autoconfig=true \
      -Dspring.graal.remove-yaml-support=true \
      -cp target/spring-boot-graal.jar
    

    这个过程可能有点长,建议你起来喝杯水或者喝杯咖啡!这需要一些时间,具体取决于您的硬件!示例项目大约需要3-4分钟。如果一切顺利,您将在中找到本地编译的Spring Boot应用程序/target/spring-boot-graal。只需使用以下命令运行它:

    ./target/spring-boot-graal
    

    =============================

    相关文章

      网友评论

        本文标题:如何把Java程序的启动速度加快100倍?GraalVM了解一下

        本文链接:https://www.haomeiwen.com/subject/xbifxktx.html