简介
JVM (Java Virtual Machine) Java 虚拟机是物理机与高级语言之间的一层抽象层。用于封装各个硬件平台的不同,让各种高级语言只要面向虚拟机编程,不用了解硬件上的差别。最终“实现一次编写,到处运行”的目的。
Java 技术体系
广义上来讲,用 JVM 运行的 Kotlin 、 Clojure 、 JRuby 、 Groovy 等语言都属于 Java 技术体系。但按照 JCP 官方定义的 Java 技术体系分为:
- Java 程序设计语言
- 各个硬件平台上的 Java 虚拟机实现
- Class 文件格式
- Java 类库 API
- 来自商业机构和开源社区的第三方 Java 类库
JDK (Java Development Kit)是 Java语言、Java 虚拟机、 Java 类库这三部分的统称 ,是支持 Java 程序开发的最小环境。 JRE (Java Runtime Environemnt)是 Java SE API 子集和 Java 虚拟机这两部分的统称,是支持 Java 程序运行的最标准境。

上图是 Java 技术体系的各个组成部分,以及 JDK 和 JRE 所包含的范围。
JDK = JRE + Java 语言 + Java 工具
上述是按照功能组件来分的。
从产品线来划分, Java 技术体系包括:
- Java Card :支持 Java 小程序运行在小内存设备(智能卡)上的平台;
- Java ME(Micro Edition):移动终端(手机、PDA)的运行平台;
- Java SE(Standard Edition):桌面级应用的平台,提供了完整的 Java 核心 API;
- Java EE(Enterprise Edition):支持多层架构的企业级应用,这条产品线在 JDK 10 之后被 Oracle 放弃,捐献给 Eclipse 基金会管理,后称 Jakarta EE;
Java EE 针对 SE 做了很多针对性的补充,这些补充包一般以 javax.* 开头,后来一部分这些包被加入到 java.* 的核心包中。
JVM 家族
- Sun Classic/Exact VM:
- Classic 是 Java 的第一个虚拟机,只能用纯解释的方式来运行 Java 代码,如果需要即时编译器(用于将字节码编译成本机能立刻执行的机器码),则即时编译器会完全接管虚拟机的执行系统,即解释和编译只能二选一。如果外挂即时编译器,那么不管代码是否有编译价值,都会被编译,但是基于程序响应时间的压力,编译器不敢使用耗时高的优化技术,导致编译后的机器码执行效率不如 C/C++ ,解释执行就更不用说了,所以这时的 Java 代码执行很慢;
- Exact VM 由于使用了准确式内存管理(Exact Memory Management)而得名。准确式内存管理就是能准确地知道内存某个位置的数据具体是值类型还是引用类型,这可以在垃圾收集阶段判断堆上数据是否还可能被使用。Exact VM 还抛弃了 Classic VM 的基于句柄(广义指针)的对象查找方式,节省了一次间接查找的时间;
- Hotspot VM:Hotspot VM 继承了 Exact VM 的准确式内存管理,并提供了热点代码探测技术,如果一段代码被频繁调用,将会分别触发标准即时编译器和栈上替换编译(On-Stack Replacement,OSR)行为;
- Mobile/Embedded VM:这个虚拟机是面向移动端和嵌入式时常的,在现在面临 Android 和 IOS 平分天下的格局,这类虚拟机只在性能很有限的功能机上使用了;
- BEA JRockit/IBM J9 VM
- BEA JRockit:曾经是号称世界上最快的 JVM ,最开始主要面向服务器端,所以不在意程序的启动速度,所以没有解释器,完全由即时编译器构成,现已不再发展;
- IBM J9 VM:市场定位与 Hotspot 相近,模块化比 Hotspot 做的更优秀,核心组件库(垃圾收集器、即时编译器、诊断监控子系统等)都单独构成了 IBM OMR 项目,可以在其他语言平台快速组装出相应的功能;
- BEA Liquid VM/Azul VM:与特定硬件平台绑定、软硬件配合工作的专有虚拟机,具有更高的执行性能;
- Apache Harmony/Google Android Dalvik VM:Harmony VM 没有被商用过,代码被吸纳进 Dalvik VM 中,Dalvik VM 后来被 ART 虚拟机取代;
- 其他。。。
无语言倾向的虚拟机 Graal VM
Graal VM 的基本工作原理是将语言的源代码或者源代码编译后的中间格式,通过解释器转换成 Graal VM 可读的中间格式。例如对于 LLVM 语言 C/C++ 专门设计一个解释器来满足输出字节码的转换,这个过程被称为程序特化(Specialized)。这种虚拟机可以把本来运行速度不快的平台,比如 python 和 javascript 通过运行时的自动优化以达到更高的执行效率,并且无论什么语言,无论什么平台都能够在上面运行。
新一代的即时编译器 Graal 编译器
自 JDK 10 起,Hotspot VM 替换了 原有的 C2 编译器,改用 Graal 编译器。这个新编译器能够比旧编译器执行更复杂的优化,比如 部分逃逸分析(Partial Escape Analysis),也比 C2 更容易进行激进预测性优化(Aggressive Speculative Optimization),支持自定义的预测性假设;实现时,可以采用了和 C2 编译器相同的名为 Sea-of-nodes 的高级中间表示形式,更容易继承 C2 的优点。总的来说前途可期。