Native Image
GraalVM Native Image是由Oracle Labs开发的一种AOT编译器,支持基于JVM的高级语言,如Java, Scala, Clojure, Kotlin。Native Image以Java bytecode作为输入,将所有应用所需的class依赖项及runtime库打包编译生成一个单独可执行文件。具有高效的startup及较小的运行时内存开销的优势。
与传统的Java虚拟机不同,Native Image是封闭式的静态分析和编译,不支持class的动态加载,程序运行所需要的多有依赖项均在静态分析阶段完成。此外GraalVM Native Image运行在一个名为SubstrateVM的轻量级的虚拟机之上。虽说是轻量级虚拟机,SubstrateVM却拥有运行Java程序所必需的所有组件,包括deoptimizer、gc及thread scheduling等。
Native Image的运行机制如图:
关于GraalVM Native Image更多的细节可以参考链接:
https://www.graalvm.org/docs/...
Native Image编译Java应用
本节以HelloWorld为例,简要介绍Native Image如何编译和运行Java程序。在编译之前,用户需要首先安装native-image工具。本文GraalVM EE(Enterprise Edition)19.0.0为例来介绍。
1、下载安装native-image
首先官网下载GraalVM EE:
https://www.oracle.com/downlo...
解压缩之后,执行bin/gu:./graalvm-ee-19.0.0/bin/gu install native-image
之后native-image工具已经生成在bin目录下,用户即可直接使用。
2、创建HelloWorld
echo "public class HelloWorld { public static void main(String[] args) { System.out.println(\"Hello World\"); } }" > HelloWorld.java
使用javac编译生成HelloWorld的class文件:javac HelloWorld
3、生成HelloWorld native image
native-image HelloWorld
native image生成过程及时间如下图:
至此helloworld的可执行image已经生成,名为“helloworld”。直接执行即可看到运行结果:./helloworld
Hello World
Native Image对Java动态特性的处理
目前GraalVM Native Image并没有完全支持多有的Java动态特性,如不支持class动态加载。
由于Native Image是静态分析及AOT编译,编译器不能完全准确地预估目标应用所依赖的所有动态特性。为了保证功能的完整性,GraalVM Native Image为以下四种动态特性提供了特殊处理:
1)Java Native interface (JNI)
2) Java Reflection
3) Dynamic proxy (java.lang.reflect.Proxy)
4) Class path resources (Class.getResource)
Native Image提供一个tracing agent来搜集所有动态特性的具体使用细节,搜集需要预先使用传统的java虚拟机运行应用程序来完成。具体命令如下:java -agentlib:native-image-agent=config-output-dir=./config/ HelloWorld
java -agentlib:native-image-agent=config-merge-dir=./config/ HelloWorld
生成的所有配置信息会以.json的形式存放于用户指定的目录下,如“./config” :ls ./config
jni-config.json proxy-config.json reflect-config.json resource-config.json
配置信息生成好之后,native-image可以通过使用option “–H:ConfigurationFileDirectories=./config/” 来为编译器提供具体信息:/native-image –H:ConfigurationFileDirectories=./config/ HelloWorld
更多具体细节可参考:
https://github.com/oracle/gra...
源码说明
目前GraalVM Native Image仅支持X86和AArch64平台。该项目属于Oracle Labs的开源项目,有兴趣的同学可以去下载看看。
源码链接:
https://github.com/oracle/gra...
所有对源码的编译及使用可以参考:
https://github.com/oracle/gra...
值得一提的是,对SubstrateVM在AArch64平台的编译,需要使用的jdk版本目前仅支持Oracle Labs jdk11:
https://github.com/graalvm/la...