当前位置: 首页 > news >正文

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

56cd93413dcb56caca5eed5654f78b6d.gif

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

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

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

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

9b6d4a7f470e5d999623c457b9a72039.png

难道使用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静态编译:原理与应用》

    7a60f58ee6dfab976db1e6340a2439f3.png478c6b96593b378b71910c2c7b411aed.png

f0875d1bc94c3db97e08f91970d0c800.png

4c2299fedbdbcd3ae54766655d5075eb.png

本书特色

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

  • 多名专家联袂推荐:

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

  • 阿里资深专家撰写:

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

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

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

  • 全方位落地指导:

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

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

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

 

43ab7315f27b0179a9a9784d1272551f.png

34984670584990ee40a8934d996a27f5.png

本书结构

本书分为三部分,分别从应用、实现原理和具体实例三个方面进行阐述。

  • 第一部分

    从整体上介绍GraalVM项目及其静态编译子项目Substrate VM。

  • 第1章向读者介绍Java静态编译产生的技术原因——Java冷启动问题的产生和由来。

  • 第2章首先对GraalVM做概要介绍,然后分别介绍Substrate VM和方舟编译器这两种实现方案,并对比它们的技术特点。

  • 第3章向读者介绍Oracle GraalVM项目的整体结构。

  • 第4章介绍使用GraalVM静态编译Java应用的详细步骤。

  • 第二部分

    主要介绍GraalVM中静态编译框架子项目Substrate VM的实现原理。

  • 第5章介绍Substrate VM静态编译框架的实现与总体流程。

  • 第6章介绍Substrate VM中的功能扩展机制——Feature机制,框架中的各个具体功能点都是通过该机制实现的。

  • 第7章介绍编译时的程序元素替换功能——Substitution机制,该机制实现了无侵入性的程序元素替换能力,在静态编译框架的运行时实现中有基础性的地位。

  • 第8章介绍Substrate VM的类提前初始化优化技术,该技术将符合条件的类在编译时初始化,不但节省了运行时初始化的开销,而且无须分析已经运行过的类初始化函数,因此降低了编译时的静态分析开销。

  • 第9章和第10章分别介绍两种具有代表性的Java动态特性—反射和序列化的静态化实现过程。

  • 第11章和第12章介绍Substrate VM的跨语言编程能力。

  • 第三部分

    通过两个实例介绍Java静态编译技术的实践,并在最后介绍程序在静态编译后的产物native image的调试方法。

  • 第13章介绍云原生应用的静态编译和部署实例,侧重云服务平台的部署和性能比较。

  • 第14章介绍用Java实现JVMTI Agent的实例,侧重Substrate VM框架对JVMTI编程的支持。

  • 第15章介绍对native image的调试支持,静态编译后的Java程序已经是本地程序,不再支持原先的Java调试方式,而只能通过GDB调试。本章介绍如何用GDB调试native image程序。

2398d69c4d9b9f12b8aa247efe676402.png

305cb8c0cebccce4ba723fb14ecdec20.gif

5cd089619c639a2b8ca491f8290e8f5d.png

扫码关注【华章计算机】视频号

每天来听华章哥讲书

cd2478d1d6c62fabf63874286059d7e6.gif

更多精彩回顾

书讯 | 1月书讯(下)| 2022年的第一本书

书讯 | 1月书讯(上)| 2022年的第一本书

资讯 | 重磅!达摩院发布2022十大科技趋势

书单 | 6本书,读懂2022年最火的边缘计算

干货 | Flink1.14.2发布,除了log4j漏洞你还需要关注什么?

收藏 | Docker冲顶技术热词,微服务应用热度不减,中国云原生开发者真实现状如何?

上新 | 【新书速递】金融领域可解释机器学习模型与实践

a579a5c5eca33476e8d0b64cca6e6d8e.gif

1b42cac83827580044f8b92763ed03d9.gif

点击阅读全文了解本书详细目录

相关文章:

  • 脑机接口新进展!只凭意念,操纵机器移动、拿取物体成为现实
  • 【第87期】程序员怎样上元宇宙的车?
  • 什么是贝叶斯定理?朴素贝叶斯有多“朴素”?终于有人讲明白了
  • 数据中台怎么选型?终于有人讲明白了
  • 一幅真实的产品世界全景图,产品小白向上突破必看!
  • 自主IT行业生态需要会造计算机的人才
  • AI正在模仿人类大脑!2021年10篇顶会论文:大脑也在「无监督」学习
  • 终于有人把“嵌入式人工智能”讲明白了
  • 数据分析的 5 种归纳方法
  • 四位RISC先驱获「工程学界诺贝尔奖」,图灵奖得主David Patterson、John Hennessy获奖...
  • 【第88期】这10本硬核技术书,带你读懂5G、物联网和边缘计算,玩转元宇宙
  • 抖音的推荐技术这么强,为什么还有人觉得推荐的一点都不准呢?
  • 【新书速递】如何高效学习存储系统?一本书全都讲明白
  • 学会这10个设计原则,离架构师又进了一步!!!
  • Electron开发者该如何提升自己的技能水平
  • #Java异常处理
  • Docker: 容器互访的三种方式
  • es6要点
  • JAVA_NIO系列——Channel和Buffer详解
  • Java精华积累:初学者都应该搞懂的问题
  • Java深入 - 深入理解Java集合
  • JDK 6和JDK 7中的substring()方法
  • laravel5.5 视图共享数据
  • python 装饰器(一)
  • 多线程 start 和 run 方法到底有什么区别?
  • 将 Measurements 和 Units 应用到物理学
  • 前端攻城师
  • 数据科学 第 3 章 11 字符串处理
  • 微信小程序设置上一页数据
  • 新版博客前端前瞻
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (3)选择元素——(17)练习(Exercises)
  • (c语言)strcpy函数用法
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (十一)图像的罗伯特梯度锐化
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)c++ std::pair 与 std::make
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .equals()到底是什么意思?
  • .NET : 在VS2008中计算代码度量值
  • .NET 动态调用WebService + WSE + UsernameToken
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .net6Api后台+uniapp导出Excel
  • .NET的数据绑定
  • .NET和.COM和.CN域名区别
  • .NET框架设计—常被忽视的C#设计技巧
  • .NET面试题(二)
  • .net中的Queue和Stack
  • .py文件应该怎样打开?
  • .sdf和.msp文件读取