Java虚拟机的发展历史

从 Java1.0 说到了 Java1.9,从 1995 年说到了 2017 年,在这 20 余年的发展过程中,Java 在全世界得到了广泛普及,成为了世界上使用人数最多的编程语言。

值得表明的是,Java 的高速发展离不开底层技术的支持,离不开 Java 的核心 — 虚拟机。在这 20 多年的发展中,Java 虚拟机也随着 Java 的版本不断的迭代,更新。

从 1996 年初,Sun 公司发布的 Java1.0 开始,虚拟机就走进了历史的舞台。在发展的过程中,有的虚拟机一经出现便得到众多关注,有的虚拟机时运不济诞生没多久便早早夭折。

在这一节中,我们一起来回顾下 Java 虚拟机家族的发展轨迹和历史变迁。

Sun Classic VM

1996 年 1 月 23 日 Sun 公司发布了 JDK1.0,并推出了世界上第一款商用 Java 虚拟机 —-Sun Classic VM。不过,该款虚拟机只能使用纯解释器的方式来执行 Java 代码,如果需要使用 JIT(即时编译器 Just In Time Compiler),就必须进行外挂操作。但是,如果外挂了 JIT(即时编译器 Just In Time Compiler),解释器就不会在起作用了,JIT(即时编译器 Just In Time Compiler)会完全接管了虚拟机的执行。 悲剧的是,如果 JIT(即时编译器 Just In Time Compiler)完全接管了虚拟机,将会导致整个 Java 程序的执行效率大大降低。

“Java 语言执行慢 “就是在此时树立起来的,怪我虚拟机咯?

为什么说,JIT 会导致 Java 程序执行效率大大降低呢?因为 JIT 会对程序中的每一个方法、每一行代码进行编译,在程序执行时候每执行一个方法就会进行一次编译,那么可想而知,如果碰到编译耗时较高的代码,对于程序的执行简直就是灾难,想必没有人会忍受如此之慢的程序。

什么是解释器,什么是编译器,什么是 JIT?

Java 编译器: 虚拟机将源代码(.java 文件)编译成一种中间的字节码(.class 文件),这种字节码就是 JVM 所能看懂的语言, 这与平台无关,这也是 Java 能跨平台操作的核心,拿着. class 文件在任何平台都可以运行。

Java 解释器: 用来解释执行 Java 编译器编译后的字节码文件,把字节码转化为特定平台所能看懂的机器码并运行。编译后的字节码文件一行一行解释运行,解释器不会一次把整个程序翻译出来,而是每解释一行代码就运行一次,然后再翻译下一行,再运行,如此不停地进行下去。因此解释器的程序运行速度比较缓慢。

即时编译 (Just-in-time compilation: JIT):又叫实时编译、及时编译,是指一种在 Java 程序运行时将字节码编译成平台所能看懂的原生机器码技术,并且会将翻译过的机器码缓存起来以便下次执行时候,直接使用,提高程序的性能,这项技术是被用来改善虚拟机执行效率的。此外,JIT 只会对经常执行的字节码进行编译。

虚拟机特点

Java 语言的一个非常重要的特点就是与平台的无关性,而 Java 虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码,而引入 Java 虚拟机后,Java 语言在不同平台上运行时不需要重新编译。所以可以实现,一次编译到处运行。

Java 虚拟机屏蔽了与具体平台相关的信息,使得 Java 编译程序只需生成在 Java 虚拟机上运行的目标代码(字节码),就可以在多平台上不加修改地运行。Java 虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令进行执行。

Exact VM

Sun Classic VM 的诞生,为 Java 提供了更为广阔的发展空间,但是 Sun Classic VM 也存在这致命的缺陷。

为了解决 Sun Classic VM 所面临的效率问题,Sun 公司在 Java1.2 时候发布了名为 Exact VM 的虚拟机,这款虚拟机的执行系统采用的是两级即时编译器、编译器和解释器混合工作模式等,同时 Exact VM 采用准确式内存管理,也就是说虚拟机知道内存中的某个位置上的数据是什么类型的,例如说:这个位置是一个数字 123 的 reference 类型,还是就是数字 123。有了这样的功能后,虚拟机在垃圾收集时就可以准确的判断出这些数据是否可用,继而大大提高了垃圾回收的效率。

虽然 Exact VM 在技术上比 Sun Classic VM 先进了许多,但不幸的是,没诞生多久就被后来更为优秀的 HotSpot VM 所取代,早早夭折了。甚至还没有发布 windows 和 linux 平台下的商用版本。

Sun HotSpot VM

说起 Sun HotSpot VM,想必所有 Java 程序员都应该知道。当我们在命令窗口使用 java -version 命令时,会出现如下输出:

其中,Java HotSpot(TM) 64-Bit Server VM 就是我们当前 Java 版本中所默认的虚拟机。也就是本小节的主角 —Sun HotSpot VM。

HotSpot VM 最初并非 Sun 公司开发的,而是由一家名为 “Longview Technologies” 的小公司设计的,而且这款虚拟机一开始也不是为 Java 语言开发的。

不过,在当时 HotSpot VM 这款虚拟机在 JIT 编译技术上拥有许多优秀的理念,于是 Sun 公司在 1997 年收购了 Longview Technologies,并获得了 HotSpot VM。

正所谓人如其名,Sun HotSpot VM 不但继承了之前两款 Sun Classic VM、Exact VM 虚拟机的特点,还有很多自己的特征。通过名字便可看出,HotSpot— 热点,即热点代码探测技术。

我们之前说了,在 Sun Classic VM 时,如果如果外挂了 JIT,解释器就不会在起作用了,JIT 会完全接管了虚拟机的执行,在运行时期会对每一行代码进行编译,大大影响程序的执行效率。

当 Sun HotSpot VM 出现后,这一情况逐渐被改善。HotSpot VM 所拥有的热点代码探测技术,会对方法的执行进行统计。当一个方法被多次执行时,HotSpot VM 就会将该方法交给 JIT,让 JIT 对其进行编译,并将编译后的机器码缓存起来,以供下一次调用。通过不断的优化,Java 程序的执行效率得到了很大提升。

HotSpot VM 所拥有的热点代码探测技术,是通过执行计数器来实现的。主要是对每个方法建立计数器,统计方法的执行次数,如果执行次数超过了一定的阀值,虚拟机就认定其是热点方法。

值得注意的是,这里统计的执行次数,是指在一定时间内的执行次数,我们称之为频率。当超过规定的时间后,方法的调用次数如果达不到热点代码的要求,那么该方法的调用次数就会进行热度衰减,次数的值将会变为原来的一半。

2006 年,JavaOne 大会,Sun 公司宣布将 Java 进行开源,并在 GPL 协议下公开了源码,在此基础上建立了 OpenJDK(大部分内容与 Sun Java 一致)。而 Sun HotSpot VM 也就成为了 Sun JDK 和 OpenJDK 的公共虚拟机。

在 Java1.3 时,HotSpot VM 成为了 Java 默认的虚拟机(不幸的 Exact VM 早已被打入冷宫,据说在 Sun 公司内部还进行了激烈的讨论,到底是选择 HotSpot VM 还是 Exact VM)。有趣的是,第一代商用虚拟机 Classic VM 在 Java1.0、Java1.1、Java1.2 时仍是首选默认,在 Java1.3 时成为了 HotSpot VM 的备份,直到 Java1.4 时完全退出虚拟机的历史舞台。

BEA JRockit

除了 Sun 公司以外,其他组织、公司也研发出不少虚拟机实现,下面我们就来一一介绍。

BEA JRockit 曾号称是 “世界上速度最快的 Java 虚拟机”,是 BEA 公司在 2002 年从 Appeal Virtual Machines 公司收购得来的。有意思的是,Oracle 后面又把 BEA 公司收购了。所以 JRockit 现在隶属于 Oracle;

说到 BEA 大家可能不太熟悉,但是如果问到 weblogic,想必许多人都听说过。没错,weblogic 就是 BEA 公司的一个重量级产品,与 tomcat 一样,也是一个开发、集成、部署和管理大型分布式 Web 应用、网络应用和数据库应用的 Java 应用服务器。最早由一个小公司开发,后来被 BEA 公司收购。

与其他的虚拟机不同的是,BEA JRockit 旨在驱动要求极高的服务器端 Java 应用,以便为企业应用提供极高的性能、可管理性和可靠性。

在 BEA 收购 JRockit 之后,BEA 公司将其发展成一款专门为服务器硬件和服务器端应用场景高度优化的虚拟机,说直白点,就是该虚拟机对于特定场景的应用更合适,例如高并发,进行了一些深度的优化操作,执行速度上远远超过 HotSpot VM.

值得一提的是,JRockit 还是一个专门针对于 Intel 处理器进行优化的 JVM,BEA JRockit 采用了最先进的优化技术,能在 Intel 处理器上获得最高的性能,其中包括支持 64 位的英特尔至强和英特尔安腾处理器。

JRockit 使用了自适应的优化编译器,以加速字节代码的执行。内部功能如线程同步、对象分配、数组复制和文件 / 网络通信均针对速度进行了优化。

不幸的是,由于 Oracle 后面即收购了 BEA 公司,也收购了 Sun 公司,所以在 Java SE 虚拟机的选择上,BEA 也成为了炮灰,只有 HotSpot VM 一家独大了。JRockit 最后发布的大版本是 R28,只支持到了 Java1.6,原本在开发中的 R29 及 JDK7 的对应功能都没来得及完成项目就被终止了。

可以吹吹牛逼的是,在曾经的 Java SE 主流虚拟机中,Rockit 跟 HotSpot 与 J9 一起并称三大主流 JVM。

IBM J9 VM

IBM 最初研发了多款 Java 虚拟机,不幸的是,经过多年的发展,许多虚拟机不是被合并就是被淘汰了。现在主推的就是我们本小节要介绍的 IBM J9 虚拟机。

IBM J9 是 IBM 开发的一个高度模块化的 JVM。

与 JRockit 不同,IBM J9 的市场定位与 Sun HotSpot VM 类似,是一款从服务器端到桌面应用再到嵌入式等场景都涉及的虚拟机,但是, 在中国 IBM J9 的普及程度远不及 HotSpot 或 JRockit。

由于 IBM 自身发展问题,IBM J9 至今连一份完整的中文文档都很难找到。关于 IBM J9 的大部分信息,很多都是在其 IBM 内部平台上进行共享,直接对外公布的相对较少。

并且,在 Window 上 IBM 与 Oracle 有协议,IBM 不能再 Window 平台上单独发布 IBM J9 虚拟机。如果想要使用 IBM J9,那么就得使用 IBM 的相关产品,因为这些产品中都或多或少的绑定了 IBM J9 虚拟机,例如:WAS、Rational 系列的产品,又或者 Lotus 系列的产品。

在 2017 年 9 月份,IBM 曾宣布开源 IBM J9 虚拟机,并命名为 OpenJ9,已将该项目托管至 GitHub,OpenJ9 已贡献给 Eclipse 基金会。

对于 IBM 为什么将他们的 J9 虚拟机贡献给 Eclipse 基金会的问题,IBM 这样回应:IBM 公开承诺要将创新带入开源社区。OpenJ9 虚拟机本身是基于 Eclipse OMR 项目的核心技术组件,OMR 由 IBM 在 2016 年贡献给 Eclipse 基金会。IBM 一直在持续将资源投入到 Eclipse OpenJ9 和 Eclipse OMR 中,以确保其企业产品能够利用最新的硬体技术。」

Azul VM

Azul VM 是 Azul System 公司在 Sun HotSpot VM 基础上进行大量改进后的产品,运行在 Azul System 公司专有 Vega 平台上。Vega 是 Azul System 公司主打的硬件 / 软件的混合解决方案。Vega 中使用的是自行设计的 Vega/TXU CPU,定制的内存和主板,自行研发的操作系统,所以说是一个软硬结合的混合解决方案。

重要的是,每个 Azul VM 可以管理数十个 CPU 和数百 GB 内存的硬件资源,可不可怕。更为关键的是,在如此大的内存下,Azul VM 还能可控的 GC 时间的垃圾收集器。

Vega 于 2005 年首次投向市场。到 2009 服务器硬件市场疲软后,Azul 转向研发 Azul Zing 虚拟机,于 2010 年发布,而 Vega 硬件设计部门最终就解散了。

Azul Zing VM

在 Vega 平台发展不利的情况下,Azul 在 2010 年发布了 Java 虚拟机 —-Zing VM。Azul Zing JVM 是在 HotSopt VM 上做了不少的定制以及优化工作,改进了许多会影响延迟的细节。

Azul Zing JVM 主打低延迟、高实时服务器端 JDK 市场,最大的卖点是:(1) 低延迟、“无暂停”(pauseless)的 C4 GC,GC 带来的暂停可以控制在 10ms 以下的级别,支持的 Java 堆大小可以到 1TB。(2) 启动后快速预热功能,“ReadyNow!”。(3) 可管理性:整合在 JVM 内的监控工具 Zing Vision。Azul Zing 并不单纯拥有虚拟机,如果算上 Zing System Tools 的话,Azul Zing 是一套纯软件解决方案,并且可以运行在 Linux、x86-64 平台上。

Zing JVM 发行版同样包括了产品应用可视化工具,称做 Zing Vision,它提供了以一套工具用实时获取故障程序的信息。在 5.2 版本有一些功能上的增强,例如在安全的时刻去收集更多的垃圾回收统计数据。

Azul Zing VM 基于 Sun HotSpot VM,针对 Linux 和 x86 平台进行了优化。Azul Zing VM 5.2 版本支持以下 Linux 发行版:

  1. Red Hat Enterprise Linux 5.2以上, 6.x
  2. SUSE Linux Enterprise Server SLES 11 sp1sp2
  3. CentOS 5.2以上, 6.x
  4. Ubuntu Linux 10.04 LTS, 12.04 LTS -Zing 5.2版本新支持的平台

Microsoft JVM

微软曾经也是 Java 技术的铁杆支持者,可惜 Sun 公司在 2000 年左右以侵犯商标、不正当竞争等罪名起诉微软。最终,Sun 公司胜诉,微软赔偿 Sun 公司 10 亿美元,并承诺永久停止 Microsoft JVM 的发展,并逐步在微软产品中移除 Microsoft JVM 相关功能。在 Window XP SP3 版本中,Microsoft JVM 的内容被全部抹去。

Sun 公司当时为什么要这么做?主要原因还是 Sun 公司和微软形成了竞争关系,并且此竞争关系威胁到了 Sun 公司的地位。而微软的目的也很直接,就是与 Sun 公司争夺 Java 的控制权,使得 Java 从跨平台技术变为绑定在 Windows 上的技术。或许,Sun 公司当时也是被逼无奈。

在 Java 语言诞生初期,Java 主要的应用就是在浏览器中运行,微软为了在浏览器中支持 Java 程序,便开发了自己的虚拟机产品,当然这款产品只有 Windows 平台版本。不过,由于微软强大的研发实力,在当时 Microsoft JVM 可是性能最好的虚拟机。可是好景不长,Sun 公司于 1997 年 10 月提起了诉讼。

TaobaoVM

使用Java技术编写的系统,无疑在生产环境中需要对Java虚拟机进行正常的调优工作,既然谈到Java虚拟机的调优技术,笔者相信大部分的开发人员至今仍然仅停留在参数调制上。由于淘宝目前无疑是中国的Java技术应用方,那么淘宝究竟是采用什么样的技术对Java虚拟机进行优化的呢?淘宝的技术团队对Java虚拟机的优化工作其实早已不是停留在简单的参数调制上面,而是充分结合了企业自身的业务特点以及实际的应用场景,在OpenJDK的基础之上通过修改大量的HotSpot源代码,深度定制了淘宝专属的高性能Java虚拟机——TaobaoVM。

既然是结合业务特点深度定制的一款Java虚拟机,那么性能必然在某一些特定的应用场景上会比Oracle官方的HotSpot更强,如图1-8所示。但其弊端同样也非常明显,那就是无法实现通用。所以如果只是想对TaobaoVM进行研究的话,可以参考jvm.taobao.org中的描述编译一个TaobaoVM,但如果需要应用在实际的项目中,笔者还是建议三思而后行,否则将会得不偿失。

淘宝的技术团队通过修改大量的HotSpot源代码深度定制的TaobaoVM,其实从严格意义上来说,在提升Java虚拟机性能的同时,却严重依赖物理CPU类型。也就是说,部署有TaobaoVM的服务器中,CPU全都是清一色的Intel CPU,且编译手段采用的是Intel C/CPP Compiler进行编译,以此对GC性能进行提升。除了优化编译效果外,TaobaoVM还使用了crc32指令实现JVM intrinsic降低JNI的调用开销,如图1-9所示。

除了在性能优化方面下足了功夫,TaobaoVM还在HotSpot的基础之上大幅度扩充了一些特定的增强实现。比如创新的GCIH(GC invisible heap)技术实现off-heap,这样一来就可以将生命周期较长的Java对象从heap中移至heap之外,并且GC不能管理GCIH内部的Java对象,这样做的好处就是降低了GC的回收平率以及提升了GC的回收效率,并且GCIH中的对象还能够在多个Java虚拟机进程中实现共享。其他扩充技术还有利用PMU hardware的Java profiling tool和诊断协助功能等。

华为毕昇 JDK 8

根据介绍,毕昇 JDK 是华为内部 OpenJDK 定制版 Huawei JDK 的开源版本,它是一个高性能、可用于生产环境的 OpenJDK 发行版。Huawei JDK 运行在华为内部 500 多个产品上,积累了大量使用场景和 Java 开发者反馈的问题和诉求,解决了业务实际运行中遇到的多个问题,并在 ARM 架构上进行了性能优化,毕昇 JDK 运行在大数据等场景下可以获得更好的性能。

毕昇 JDK 8 与 Java SE 标准兼容,8u262 包含的 IANA 版本是 2020a。目前该 JDK 仅支持 Linux 版本,对操作系统的要求是 AArch64 上 glibc 版本不低于 2.17,基本覆盖所有主流操作系统,发布前经过稳定性验证的操作系统有 openEuler 20.03 LTS 和 CentOS 7.X。

返回笔记列表
入门小站