第1章 走近Java
1.2 Java技术体系
从广义上讲,Kotlin、Clojure、JRuby、Groovy等运行于Java虚拟机上的编程语言及其相关的程序都属于Java技术体系中的一员。
Java EE在JDK 10以后被Oracle放弃,捐献给Eclipse基金会管理,此后被称为Jakarta EE。
1.5 展望Java技术的未来
1.5.1 无语言倾向
Graal VM是一个在HotSpot虚拟机基础上增强而成的跨语言全栈虚拟机。
1.5.2 新一代即时编译器
对需要长时间运行的应用来说,由于经过充分预热,热点代码会被HotSpot的探测机制准确定位捕获,并将其编译为物理硬件可直接执行的机器码,在这类应用中Java的运行效率很大程度上取决于即时编译器所输出的代码质量。
HotSpot虚拟机中含有两个即时编译器,分别是编译耗时短但输出代码优化程度较低的客户端编译器(简称为C1)以及编译耗时长但输出代码优化质量也更高的服务端编译器(简称为C2)。
自JDK 10起,HotSpot中又加入了一个全新的即时编译器:Graal编译器,看名字就可以联想到它是来自于前一节提到的Graal VM。Graal编译器是以C2编译器替代者的身份登场的。开发效率及扩展性上都要显著优于C2编译器。
可以使用-XX:+UnlockExperimentalVMOptions -XX:+UselVMCICompiler
参数来启用Graal编译器。
1.5.3 向Native迈进
提前编译(Ahead of Time Compilation,AOT)是相对于即时编译的概念,提前编译能带来的最大好处是Java虚拟机加载这译成二进制机器码。理论上,提前编译可以减少即时编译带来的预热时间,减少Java应用长期给人带来的“第一次运行慢”的不良体验,可以放心地进行很多全程序的分析行为,可以使用时间压力更大的优化措施。
但是提前编译的坏处也很明显,它破坏了Java“一次编写,到处运行”的承诺,必须为每个不同的硬件、操作系统去编译对应的发行包;也显著降低了Java链接过程的动态性,必须要求加载的代码在编译期就是全部已知的,而不能在运行期才确定,否则就只能舍弃掉已经提前编译好的版本,退回到原来的即时编译执行状态。
Substrate VM 是在Graal VM 0.20版本里新出现的一个极小型的运行时环境,包括了独立的异常处理、同步调度、线程管理、内存管理(垃圾收集)和JNI访问等组件,目标是代替HotSpot用来支持提前编译后的程序执行。它还包含了一个本地镜像的构造器(Native ImageGenerator),用于为用户程序建立基于Substrate VM的本地运行时镜像。这个构造器采用指针分析(Points-To Analysis)技术,从用户提供的程序入口出发,搜索所有可达的代码。在搜索的同时,它还将执行初始化代码,并在最终生成可执行文件时,将已初始化的堆保存至一个堆快照之中。但相应地,原理上也决定了Substrate VM必须要求目标程序是完全封闭的,即不能动态加载其他编译期不可知的代码和类库。
Substrate VM带来的好处是能显著降低内存占用及启动时间。
1.5.4 灵活的胖子
在JDK 9时期,HotSpot虚拟机开放了Java语言级别的编译器接口(Java Virtual Machine Compiler Interface,JVMCI)。Graal编译器就是通过这个接口植入到HotSpot中。
到了JDK 10,HotSpot又重构了Java虚拟机的垃圾收集器接口(Java Virtual Machine Garbage Interface),统一了其内部各款垃圾收集器的公共行为。
评论区