查看原文
其他

Java静态编译技术:突破Java“冷启动”桎梏,实现启动性能“质”的飞跃

林子熠 华章计算机 2022-10-26


                                               自1996年诞生以来,Java语言长期在最受欢迎的编程语言排行榜中占据领先地位。除了语言本身的优秀特性之外,Java语言持续演进、不断发展也是它能够保持长盛不衰的重要原因。


|Java市场份额不断下降,岌岌可危?


近年来,随着云原生浪潮的兴起,越来越多的应用被部署在了云厂商的云服务环境中,以计算资源的形式为用户提供服务。在这种趋势下,应用本身越来越小,对跨平台的需求越来越弱(因为平台问题已经由云厂商解决了),但是对应用快速启动、即起即用和高性能执行的需求越来越强。


Java程序的冷启动问题在这种场景下就显得格外突出,成为开发人员在选择编程语言时的主要减分项。根据TIOBE编程语言流行趋势索引统计,Java语言的市场占有率连年下降,在C和Python之后,排名第三。



难道使用Java语言就只能忍受冷启动问题吗?Java社区和工业界一直在探索冷启动问题的解决之道,希望使用Java的用户在享受Java丰富生态的同时,还能获得良好的启动性能。


比如OpenJDK提出的AppCDS(Application Class Data Sharing)技术,可以将已经加载的类的元数据导出到文件,在下次启动时直接从文件导入这些数据,无须再次经过类的解析和加载等过程,由此削减启动时的类加载开销。但是,因为Java的冷启动问题的根源在于JVM本身,所以在JVM之上做的各种优化的效果都是有限的,难以实现质的飞跃。


从根本上审视Java冷启动问题可以发现,启动一个Java程序并让它达到性能的峰值需要经过VM初始化→应用程序初始化→字节码解释执行→JIT编译热点函数→执行JIT编译后的本地代码(native code)等环节,且不论在这些环节上能够做出何种优化,单这么长的一条链路已足以说明冷启动问题之复杂、难解。


如果不能打破这条链路,而只是在各个环节上进行优化,恐怕很难达到理想的效果。那么是否能够打破这条长链,越过中间环节直达最后一步,像C语言一样直接将Java代码编译为本地代码执行呢?


答案是肯定的,这就是Java静态编译技术Oracle公司推出的开源高性能多语言运行平台项目GraalVM,打造了一个包括静态编译器和轻量级运行时的Java静态编译框架,可以将Java程序从字节码直接编译为本地可执行应用程序。与在JVM下执行相比,静态编译后的Java程序的启动速度最高能够提升两个数量级,完全解决了冷启动问题,实现了Java应用程序启动性能的质的突破。


|什么是Java静态编译技术?


虽然冷启动问题在传统Java的框架内无法被彻底解决,但并不意味着使用Java语言就只能选择忍受冷启动问题,也不是说为了解决冷启动问题就只能放弃Java语言而转投诸如Go等不存在冷启动问题的语言。近年兴起的Java静态编译技术就彻底解决了Java语言的冷启动问题,还因为打破了Java语言与本地代码(native code)之间的界限,为Java世界解锁了更多的特性。


Java静态编译是指将Java程序的字节码在单独的离线阶段编译为汇编代码,其输入为Java的字节码,输出为操作系统本地原生程序。“静态”是相对传统Java程序的动态性而言的,因为传统Java程序是在运行时动态地解释执行和实时编译,所以静态编译需要在执行前就完成程序的编译。


静态编译的基本原则是封闭性假设(closed world assumption),要求编译器在编译时必须掌握运行时所需的全部信息,换句话说,就是运行时不能出现任何编译时未知的内容。这是因为应用程序的可达范围在静态编译时被限定了,因为没有了类加载器、解释器等组件,不能在运行时解析和执行任何动态引入的类。


|与传统Java运行模型相比,静态编译运行模型有两大特点:


一是执行的程序是与平台相关的经过编译优化的本地代码。执行本地代码不再需要经过解释执行和JIT编译,既避免了解释执行的低效,也避免了JIT编译的CPU开销,还解决了传统Java执行模型中无法充分预热,始终存在解释执行的问题,因此可以保证应用程序始终以稳定的性能执行,不会出现大的性能波动。


二是静态编译后的可执行程序自包含了轻量级运行时支持,不再额外需要JVM的支持。没有了JVM,自然也就消除了VM初始化的开销,使得应用程序可以实现“启动即峰值”的特点。另外,因为JVM的运行也需要消耗一部分内存,去掉JVM后应用程序的内存占用也大幅降低。


这两个基本特点解决了Java程序冷启动问题—JVM初始化的开销和从解释执行到JIT编译执行的开销,因此静态编译后的Java程序可以获得极速启动的效果。


解决冷启动问题,实现应用程序的极速启动,因此不再需要预热,降低了用户维持应用热度的成本。


实现程序自举,无须JVM,降低了应用程序自身所需的内存。


打破了Java程序与本地代码之间的边界,JNI调用的开销减少。


Java程序可以被静态编译为本地共享库文件,然后被其他native程序(C/C++程序)直接调用,这就意味着可以用Java语言编写C程序的库文件。


新的编程语言如雨后春笋般竞相冒出,已有的语言也在不断改进。纵观历史,有几门语言像常青树一样始终占据编程语言的主导地位,比如C、C++和Java。因此,研究Java的优化实现是非常有意义的。




目前关于GraalVM静态编译的大多数资料都是开发团队发布的技术文档、博客和GitHub上的开发相关问题讨论,而缺少系统全面性的资料介绍,尤其缺乏中文资料。因此国内的广大程序开发者和技术爱好者对其并不了解。


为了填补这方面的空白,使读者能够系统性了解并掌握GraalVM静态编译技术。推荐阅读这本由阿里静态编译研究团队的核心成员林子熠撰写的《GraalVM与Java静态编译:原理与应用》


    




本书特色






本书将为读者详细解释GraalVM中的Java静态编译技术,不仅带你了解GraalVM的静态编译框架的使用方法,更重要的是向你介绍其背后的实现原理。


  • 多名专家联袂推荐:

北京大学计算机科学技术系主任胡振江教授、阿里云基础软件掌门人蔡景现(多隆)、华为方舟编译器总架构师叶寒栋、GraalVM核心开发人员郑雨迪联袂推荐。

 

  • 阿里资深专家撰写:

作者林子熠是阿里静态编译研究团队的核心成员,曾任华为高级工程师,一直从事静态编译技术的研究与落地。

 

  • Java应用性能提升制胜法宝:

通过静态编译技术实现Java应用冷启动,实现性能质的飞跃。

 

  • 全方位落地指导:

深入原理,给出具体应用与调试技术,指导读者做好平稳落地工作。

 

  • 一站式掌握Java静态编译:

从生态、主流产品、执行流程与实现机制,到调试工具与实践,一应俱全。

 





您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存