栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java AOT之GraalVM native image介绍以及简单长连接服务实践

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java AOT之GraalVM native image介绍以及简单长连接服务实践

Java语言有20多年的发展历史,拥有众多优秀的特性如面向对象、安全、解释性、平台无关等,该语言以及其强大的生态使其成为最重要的网络编程语言。但是随着近年来技术架构的发展,微服务逐渐趋向云原生及Serverless化,使得Java也面临如下挑战:启动缓慢、内存占用大、预热问题。

Java服务启动时首先要启动一个JVM虚拟机,然后虚拟机会加载字节码,中间还包括类的加载解析初始化。JVM运行字节码运行时有解释执行和编译两种执行方式:当系统刚启动时,JVM会以解释执行并检测热点代码,热点代码会通过c1c2编译器进行编译成本地二进制代码。通过这样的机制,Java实现了很多诸如反射、动态代理等运行时的机制,例如可以在程序运行过程中加载并编译一段代码,而这个在静态编译中却不可想象。运行时编译还有个好处是可以做比较激进的编译优化,通过c2编译器和分支预测Java在某些场景下可以表现出比c++更强劲的性能。但这些优点也是有价的,包括启动耗时、预热耗时以及服务内存占用。

Graalvm

Graalvm是Oracle公司提供的一个高性能、云原生、多语言的虚拟机。除了运行 Java 和基于 JVM 的语言之外,GraalVM 的语言实现框架 (Truffle)使得在 JVM 上运行 Javascript、Ruby、Python 和许多其他流行语言成为可能。借助 GraalVM Truffle,Java 和其他支持的语言可以直接互操作,并在同一内存空间中来回传递数据。

Native Image是一种将Java代码提前编译为独立可执行文件的技术,此刻执行文件包括应用程序类、依赖、运行时库以及JDK静态连接的本机代码。Graalvm通过子模块SubstrateVM来支持Native Image,相比JVM其生成的程序具有更快的启动时间和更低的运行时开销。

SubstrateVM

SubstrateVM是GraalVM实现静态编译的基础,可以从支持静态编译以及运行时两方面来简单了解。

静态编译

应用程序、第三方库和JDK字节码共同组成了静态编译的输入,SubstrateVM会对输入进行静态分析,找到其中可达代码,然后可达代码将会有静态编译器进行编译,最终得到native image。值得注意的是由于只会编译可达的代码,所以其生成的文件相对会较小。静态分析输出是控制流图(Control Flow Graph)和类型流图(Type Flow Graph),其耗时也为整个编译流程中最长。

运行时

Native image运行需要提供垃圾回收、类初始化检查、异常处理、多线程等支持。SubstrateVM通过Java做轻量化VM运行时实现。并且通过静态编译,将运行时支持一起编译至native image中,需要注意的是GraalVM社区版只提供SerialGC垃圾收集器。

实践

通过安装使用GraalVM社区版,并创建一个echo的长连接服务来实践GraalVM native image,这里的环境是MacOS。

安装GraalVM社区版

    通过Github下载GraalVM

    解压到/Library/Java/JavaVirtualMachines目录下

    打开JavaVirtualMachines目录下Contents/Home/bin校验java -version,添加JAVA_HOME环境变量

    安装native-imagegu

    gu install native-image,编译native image依赖于本地工具链,确保本地有安装glibc-devel、zlib-devel、gcc

长链服务

服务通过Netty实现一个echo服务器,主要包括以下类

启动类

Handle

Decoder

Encoder

pom.xml

先启动服务,使用nc工具测试功能,结果如下。

然后关闭服务器,用GraalVM执行静态编译,这里使用的是maven插件,执行mvn -Pnative -DskipTests package即可完成字节码编译及静态编译,编译结果如下,可以看到整个静态编译耗时还是比较长的,主要分布在静态分析和编译这两个阶段。

生成的native文件位于target包中,大小约17M,进入target目录,可用./mini-connector直接执行,用nc测试发送hello然后关闭服务器,结果如下

结论

通过GraalVM native image,可以将java服务启动时间压缩数十倍,且生成的二进制文件大小也优于包括所有依赖的jar包。

与传统Java运行模型相比,静态编译运行通过AOT避免了JIT的CPU开销,也避免了传统运行模型中一定存在的解释执行问题,使得程序性能较稳定。通过轻量化SubstrateVM实现,且也静态编译至native image中,提供了较快的vm性能和启动速度。

但是,任何技术都有优缺点。而Graalvm静态编译则需要面临解决动态类加载、反射、动态代理等动态特性的适配问题。另外通过native运行的程序,将不再适用面向传统JVM程序的调试、监控、Agent等功能。



 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/777647.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号