首页>参考读物>计算机科学与技术>软件与程序设计

GraalVM与Java静态编译:原理与应用
作者 : 林子熠 著
出版日期 : 2021-12-14
ISBN : 978-7-111-69639-1
定价 : 89.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 211
开本 : 16
原书名 :
原出版社:
属性分类: 店面
包含CD : 无CD
绝版 : 未绝版
图书简介

全书逻辑上分为3篇。
1.第1篇首先概要介绍Java编译器的演进过程,然后介绍Java静态编译的基本原理、总体能力和发展前景
2.第2篇详细介绍GraalVM如何实现Java的静态编译,着重介绍是如何支持现有Java特性。
3.第3篇主要关注GraalVM的实践应用。静态编译目前还未能达到开箱即用的状态,这一部分会介绍如何将传统Java应用编译为二进制可执行文件或静态库文件。
通过阅读本书,读者可以了解和掌握目前新的Java静态编译技术的原理、特性和优缺点,能够判断评估自己的业务是否适用于静态编译、是否值得投入资源对现有业务进行静态化改造。

图书特色

北京大学计算机科学技术系主任胡振江教授、阿里云基础软件掌门人蔡景现(多隆)、华为方舟编译器总架构师叶寒栋、GraalVM核心开发人员郑雨迪联袂推荐,阿里巴巴资深Java专家林子熠撰写
揭秘Oracle GraalVM中Java静态编译技术的特性、实现原理、应用与调试技巧,以突破Java“冷启动”桎梏,实现启动性能“质”的飞跃

图书前言

为什么写作本书
Java语言可谓程序语言界的常青藤,自1996年诞生以来,长期在最受欢迎的编程语言排行榜中占据领先地位。除了语言本身的优秀特性之外,Java语言持续演进、不断发展也是它能够保持长盛不衰的重要原因。
近年来,随着云原生浪潮的兴起,越来越多的应用被部署在了云厂商的云服务环境中,以计算资源的形式为用户提供服务。在这种趋势下,应用本身越来越小,对跨平台的需求越来越弱(因为平台问题已经由云厂商解决了),但是对应用快速启动、即起即用和高性能执行的需求越来越强。Java程序的冷启动问题在这种场景下就显得格外突出,成为开发人员在选择编程语言时的主要减分项。根据著名的TIOBE编程语言流行趋势索引统计,Java语言的市场占有率从2016年1月的21.4%跌至2021年8月的10%,在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应用程序启动性能的质的突破。目前关于GraalVM静态编译的大多数资料都是开发团队发布的技术文档、博客和GitHub上的开发相关问题讨论,而缺少系统全面性的资料介绍,尤其缺乏中文资料。因此国内的广大程序开发者和技术爱好者对其并不了解。本书旨在填补这方面的空白,使读者能够系统性了解并掌握GraalVM静态编译技术。
本书特色
本书将为读者详细解释GraalVM中的Java静态编译技术,不仅带你了解GraalVM的静态编译框架的使用方法,更重要的是向你介绍其背后的实现原理。有兴趣的读者在阅读完本书后可以独立阅读甚至修改GraalVM中的源码,并向社区提出自己的功能改进建议或Bug修复的补丁,帮助GraalVM更好地发展。本书侧重介绍GraalVM静态编译框架和运行时的应用与原理,而不太涉及编译部分。原因如下:其一,GraalVM的静态编译中使用的编译器并不专用于Java静态编译,如可用于代替HotSpot的C2编译器,其内容博大精深,足以单独成书,所以不会过多阐述;其二,Java静态编译的难点并不在于编译本身,而是在于确定编译的范围以及对JVM原本动态运行时的改造适配等,因为JVM的实时编译器早已实现对Java字节码的编译。
如何阅读本书
本书分为三部分,分别从应用、实现原理和具体实例三个方面进行阐述。
第一部分(第1~4章)从整体上介绍GraalVM项目及其静态编译子项目Substrate VM。
第1章向读者介绍Java静态编译产生的技术原因——Java冷启动问题的产生和由来。
第2章首先对GraalVM做概要介绍,然后分别介绍Substrate VM和方舟编译器这两种实现方案,并对比它们的技术特点。
第3章向读者介绍Oracle GraalVM项目的整体结构。
第4章介绍使用GraalVM静态编译Java应用的详细步骤。
第二部分(第5~12章)主要介绍GraalVM中静态编译框架子项目Substrate VM的实现原理。
第5章介绍Substrate VM静态编译框架的实现与总体流程。
第6章介绍Substrate VM中的功能扩展机制——Feature机制,框架中的各个具体功能点都是通过该机制实现的。
第7章介绍编译时的程序元素替换功能——Substitution机制,该机制实现了无侵入性的程序元素替换能力,在静态编译框架的运行时实现中有基础性的地位。
第8章介绍Substrate VM的类提前初始化优化技术,该技术将符合条件的类在编译时初始化,不但节省了运行时初始化的开销,而且无须分析已经运行过的类初始化函数,因此降低了编译时的静态分析开销。
第9章和第10章分别介绍两种具有代表性的Java动态特性—反射和序列化的静态化实现过程。
第11章和第12章介绍Substrate VM的跨语言编程能力。
第三部分(第13~15章)通过两个实例介绍Java静态编译技术的实践,并在最后介绍程序在静态编译后的产物native image的调试方法。
第13章介绍云原生应用的静态编译和部署实例,侧重云服务平台的部署和性能比较。
第14章介绍用Java实现JVMTI Agent的实例,侧重Substrate VM框架对JVMTI编程的支持。
第15章介绍对native image的调试支持,静态编译后的Java程序已经是本地程序,不再支持原先的Java调试方式,而只能通过GDB调试。本章介绍如何用GDB调试native image程序。
勘误与支持
因为时间仓促,加上笔者水平有限,书中难免有错误之处,敬请读者不吝赐教。如果你有更多的宝贵意见,欢迎发送邮件至lin.ziyi@hotmail.com,期待能得到你的真挚反馈。
致谢
本书献给我的母亲朱桂智,没有她的辛勤养育就没有我的今天。还要感谢我的家人、老师和同事们的鼓励、鞭策和支持。

上架指导

计算机\程序设计

封底文字

Java静态编译技术是一项涉及程序语言、编译、程序分析等多个计算机专业方向的高度复杂的系统工程。GraalVM是产学研相结合的典范工程项目,由学术界和工业界通力合作研发,并得到了工业界的广泛认可。本书从工业界使用和开发的角度全面介绍GraalVM的Java静态编译技术,是广大相关技术人员学习、了解Java静态编译技术,并进一步展开相关研究的入门读物。
—— 胡振江教授,北京大学计算机科学技术系主任
Java程序的静态编译是基础软件领域近年来新兴的一项革新型技术,彻底解决了Java应用的冷启动问题,使Java程序的运行时性能达到了启动即峰值的效果。GraalVM开源社区是这方面的技术引领者之一,本书系统地将GraalVM的静态编译技术介绍给读者,填补了这方面的空白。
—— 蔡景现(多隆),阿里云基础软件掌门人、阿里巴巴合伙人、淘宝创始人之一
子熠是我在华为编译器实验室的同事,从方舟编译器项目启动之初他就是主力成员。子熠在方舟项目中如鱼得水,后来加入阿里继续在Java静态编译领域深造,这时采用的系统就是GraalVM,即本书的主题。子熠在这个领域已经耕耘多年,深入研究了业界两个成熟的、产品化的Java静态编译项目,并有自己独到的体会。本书是其部分思想的结晶,我认真读过后获益匪浅。
—— 叶寒栋,华为方舟编译器总架构师
林老师是GraalVM开源项目中一位非常活跃的贡献者。他写的这本书详尽地描述了GraalVM的代码架构及工作机制,并着重介绍其中有关静态编译的子项目Substrate VM。如果你想了解云原生时代下Java的发展,那么我非常推荐从本书入手,理解诸如Spring Boot、Quarkus、Micronaut等众多Java框架是如何摆脱笨重的Java虚拟机,实现低启动时间、低内存消耗的。
—— 郑雨迪,GraalVM核心开发人员

图书目录


前言
第一部分 从解释执行到静态编译:Java的编译发展之路
第1章 Java静态编译技术的诞生2
1.1 Java程序的运行生命周期3
1.1.1 初始化4
1.1.2 程序预热5
1.2 冷启动问题8
1.3 初识Java静态编译技术11
1.3.1 什么是Java静态编译11
1.3.2 静态编译的优势12
1.3.3 静态编译的局限性13
1.4 小结15
第2章 Java静态编译的业界实现16
2.1 Oracle GraalVM16
2.1.1 GraalVM是什么17
2.1.2 GraalVM静态编译优点19
2.1.3 GraalVM静态编译缺点20
2.1.4 GraalVM发展分析21
2.2 华为方舟编译器22
2.3 小结24
第3章 GraalVM整体结构25
3.1 子项目与组件25
3.2 GraalVM编译系统工具mx29
3.3 在IDE中打开GraalVM32
3.4 小结33
第4章 从Java程序到本地代码:静态编译应用流程34
4.1 获取GraalVM JDK35
4.1.1 下载发布版35
4.1.2 下载Docker镜像37
4.2 从源码编译37
4.2.1 编译准备37
4.2.2 编译38
4.3 获取依赖库40
4.4 预执行目标应用程序41
4.5 静态编译目标应用程序43
4.5.1 命令行模式编译43
4.5.2 配置文件模式45
4.5.3 Maven插件模式46
4.5.4 Gradle插件模式47
4.6 静态编译Java程序实例48
4.6.1 静态编译HelloWorld49
4.6.2 静态编译Spring Boot应用实例50
4.7 小结52
第二部分 静态编译实现原理
第5章 Substrate VM静态编译框架54
5.1 静态编译启动器55
5.2 静态编译实现流程57
5.2.1 类载入59
5.2.2 准备60
5.2.3 静态分析61
5.2.4 全局构建63
5.2.5 编译64
5.2.6 生成image65
5.2.7 写文件65
5.3 Substrate VM运行时支持67
5.3.1 内存管理67
5.3.2 系统信号处理机制69
5.4 小结70
第6章 Feature机制71
6.1 Feature机制概览71
6.2 Feature管理73
6.2.1 注册与调用Feature73
6.2.2 Feature依赖74
6.3 Feature影响编译流程75
6.3.1 Feature函数的入参回调75
6.3.2 访问ImageSingletons单例库76
6.4 GraalFeature实现静态编译优化77
6.4.1 GraalVM编译器基础知识77
6.4.2 扩展lowering79
6.4.3 注册图的扩展插件79
6.5 Feature接口函数80
6.6 小结82
第7章 编译时替换机制83
7.1 替换机制在Substrate VM中的应用84
7.2 基于注解的替换85
7.2.1 替换类85
7.2.2 替换枚举类型87
7.2.3 替换函数88
7.2.4 替换构造函数89
7.2.5 替换类中的域90
7.2.6 替换类的静态初始化函数92
7.3 实现原理93
7.3.1 替换机制责任链93
7.3.2 确定待替换元素集合96
7.3.3 自定义替换内容98
7.4 小结98
第8章 类提前初始化优化100
8.1 Java中的类初始化100
8.2 编译时的类初始化101
8.2.1 类提前初始化的性能分析102
8.2.2 类提前初始化的安全性分析103
8.3 优化实现原理106
8.3.1 早期阶段分析107
8.3.2 中期阶段分析109
8.3.3 后期阶段分析111
8.4 手动设置类初始化时机112
8.5 小结113
第9章 反射的实现与优化114
9.1 反射在传统Java中的实现115
9.2 基于配置的支持119
9.2.1 反射配置文件119
9.2.2 配置局限性121
9.3 Substrate VM的反射实现122
9.3.1 解析配置并注册反射信息123
9.3.2 反射函数常量折叠优化124
9.3.3 函数反射调用过程优化125
9.4 其他类似动态特性的支持126
9.4.1 JNI调用127
9.4.2 动态代理127
9.4.3 资源访问128
9.4.4 序列化特性129
9.5 小结129
第10章 序列化131
10.1 序列化特性的JDK原生实现131
10.1.1 序列化/反序列化基本流程132
10.1.2 序列化中的静态编译不友好特性133
10.2 静态编译的序列化实现136
10.2.1 解决动态类加载问题136
10.2.2 解决new抽象类问题138
10.2.3 静态初始化函数检查139
10.3 局限性139
10.4 小结141
第11章 跨语言编程:用Java语言编写共享库142
11.1 样例项目cinterfacetutorial 143
11.2 共享库的Java实现源码解析145
11.2.1 声明共享库上下文145
11.2.2 实现C基本数据结构146
11.2.3 实现C的结构体继承149
11.2.4 暴露共享库API149
11.2.5 直接调用C函数152
11.2.6 共享库函数的返回值153
11.3 静态编译JNI共享库153
11.3.1 JNIDemo项目组织结构153
11.3.2 JNI库API函数的声明155
11.3.3 JNI函数编程基本过程156
11.3.4 JNI函数参数传入String157
11.3.5 自定义JNI函数指针类型158
11.3.6 调用Java函数159
11.4 小结160
第12章 CLibrary机制161
12.1 isolate161
12.1.1 错误的多线程调用:简单复用isolate162
12.1.2 正确的多线程调用:为每个线程新建isolate163
12.1.3 正确的多线程调用:映射线程与isolate164
12.2 WordBase接口系统165
12.3 注解系统167
12.3.1 @CContext注解167
12.3.2 @CEntryPoint注解172
12.3.3 @InvokeCFunctionPointer注解173
12.4 正确释放内存173
12.5 小结175
第三部分 静态编译实战
第13章 静态编译Serverless应用到阿里云函数计算平台178
13.1 阿里云函数计算平台178
13.2 静态编译基于Micronaut的Spring-Boot示例项目179
13.3 部署到阿里云180
13.4 性能比较180
13.5 小结182
第14章 native-image-agent的实现183
14.1 native-image-agent与JVMTI183
14.2 实现静态编译的JVMTI Agent185
14.3 native-image-agent的可用选项188
14.4 小结190
第15章 调试191
15.1 编译debug版本的native image191
15.2 使用GDB调试native image193
15.2.1 启动GDB194
15.2.2 增加函数断点194
15.2.3 GDB TUI分屏界面195
15.2.4 单步调试197
15.2.5 查看Java对象的值197
15.3 小结199

教学资源推荐
作者: 刘燕君,刘振安,孙忱
作者: 邱李华,曹青,郭志强
作者: 吴黎兵 周畅 宋麟
作者: 王立柱 编著
参考读物推荐
作者: [美] 欧文?山内(Owen Yamauchi) 著
作者: [澳]伦恩?拜斯(Len Bass) 英戈?韦伯(Ingo Weber) 朱黎明(Liming Zhu) 著