你好,我是方向盘(YourBatman),坐稳扶好,开始发车。
Title | Link |
所属专栏 | 【方向盘】-基本功 |
源代码 | https://github.com/yourbatman/FXP-java-ee |
程序员专用网盘公益上线啦,注册送1G超小容量,帮你实践做减法 | https://wangpan.yourbatman.cn |
Java开发软件包(Mac) | https://wangpan.yourbatman.cn/s/rEH0 提取码:javakit |
女娲工程 | http://152.136.106.14:8761 |
版本约定 | [JDK 1.0 - 17] |
前言
如何理解Java是跨平台的语言?Java是编译型语言还是解释型语言?JDK、JRE、JVM有什么区别?
这三个常见的问题,都绕不开一个主题词:JVM。每一个Javaer都知道它,可谓又爱又恨,爱它是因为难,恨它也是因为难。
本文当然不是要去“深入理解Java虚拟机”,JVM发展这么多年,已有非常非常多关于它的权威的书籍、文章、视频,虽然大都是一看就会,一做就废...
本文非常轻松,问自己这个问题:“JVM除了HotSpot,你还知道哪些?”然后一起来了解了解JVM的发展及相关产品。
正文
一个Java虚拟机(JVM)是从未被物理建成硬件假想计算机。JVM 运行编译成其虚构指令集的程序,该指令集作为称为字节码的中间表示写入存储。
在运行时,字节码必须从虚构的指令集转换为主机 CPU 的实际指令集。这可以由“口译员”即时完成。或者字节码可以被完全编译和缓存,以比通过解释器运行得更快,在一个称为即时 (JIT) 编译的过程中。
几十年来,有许多JVM 的实现。到现在的2022年,大多数都已经消失了。
基础知识
老规矩,首先来个基础知识铺垫。
什么是JVM
JVM(Java Virtual Machine),即Java虚拟机。它是Java程序的运行平台,是二进制字节码的运行环境,它有很多发行的商用版本,其中最著名的当属Oracle官方发行的,也是JDK默认的HotSpot。
JVM发展到今天,早已不是只为Java服务。它已然成为跨语言的平台。只要是符合规范的字节码文件交给它就可以执行,比如Java就是.class字节码,其它语言只需要通过各自的编译器生成遵循JVM规范的字节码文件,同样可以运行在JVM上。
JVM规范
Java语言的各个版本对应的虚拟机规范:Java Language and Virtual Machine Specifications。
JVM是虚拟机,总的来说是一种标准规范,虚拟机有很多实现版本,是本文将要介绍的内容。
JVM所处的位置
JVM运行在操作系统之上,和硬件并无直接交互。字节码文件运行在JVM之上,从而实现了字节码跨平台的效果。从下图中可以也能得出一种解决问题的思想:没有加一层解决不了的问题,如果有,那就再加一层。
跨平台是如何实现的
这里指的跨平台指的不是跨操作系统,而是交给不同操作系统上的虚拟机帮你执行了,屏蔽了底层的适配性。正所谓复杂度不会凭空消失,这里只是JVM帮你解决掉/屏蔽掉了这个复杂度。
一图胜千言:
编译器和解释器的区别
- 解释器:直接执行用编程语言编写的指令的程序。
- 编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快。
- 编译器:把源代码转换成(翻译)“低级”语言的程序。
- 解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的下面再通过表格对比二者详细区别:
编译器 | 解释器 |
高级指令转换为机器可理解的指令 | 无需转换即可直接执行高级代码 |
将一个程序作为一个整体进行翻译 | 一条一条地翻译一个程序 |
生成中间代码或目标代码 | 无中间代码 |
编译后,将创建一个可执行文件 | 每次执行都需要解释 |
编译器种类:本机编译器,交叉编译器,源到源编译器,一遍编译器,增量编译器,源编译器 | 解释器种类:字节码解释器,线程代码解释器,抽象语法树解释器 |
编译器语言:Java Scala C/C++ C# | 解释器语言:PHP、Python、Ruby、JS |
JVM发展史
- 1996年JDK 1.0发布时,发布Sun Classic VM。第一款商用虚拟机,纯解释执行。
- 1997年JDK 1.1发布时,虚拟机没有做变更。
- 1998年JDK 1.2发布时,提供了Exact VM虚拟机,但仅限运行在Solaris平台。默认虚拟机依旧是Sun Classic VM。
- Solaris系统是Sun公司研发的操作系统,是UNIX操作系统的衍生版本之一。
- 2000年JDK 1.3发布时,默认虚拟机由Sun Classic VM改为大名鼎鼎的Sun HotSopt VM。
- 此时Sun Classic VM还并未移除,作为备用。
- 2002年JDK 1.4发布时,Sun HotSpot VM站稳脚跟一直默认都现在,Sun Classic VM彻底退出商用虚拟机舞台。
- 2003年,Scala正式发布,同年Groovy也加入JVM阵营。
- 2006年JDK 6发布时的同年,OpenJDK项目简历。顺理成章,HotSopt VM也成为了OpenJDK默认虚拟机,直到现在。
- 2008年,Oracle收购BEA,得到了JRockit虚拟机。
- JRockit专注于服务器端应用,内部不包含解析器实现,号称是世界上最快的JVM。
- 2009年,Oracle收购了Sun,获得Java商标和HotSpot虚拟机商标。
- 2011年JDK 7发布时,在JDK1.7u4中,G1垃圾回收期首次路面。
- 2014年JDK 8发布,用元空间MetaSpace员工间取代了PermGen永久代。
- 2017年JDK 9发布,G1为HotSpot的默认GC,从此CMS成为历史。
- 同年,IBM的J9开源, 形成了现在的0pen J9社区。
- 2018年Android的Java侵权案判决,Google赔偿Oracle计88亿美元。
- 同年,Oracle宣告JavaEE成为历史名词,JDBC、JMS、 Servlet赠予Eclipse基金会。
- 2020、2021、2022。
三大商用虚拟机
在Oracle还没收购Sun公司之前,JVM虚拟器呈现三足鼎立的局面,各具优势,它们是:
- SUN公司的Hotspot:聊到虚拟机时,若没做特殊说明,指的就是HotSpot。它是官方出品,纯正血统。它的特点/优势是:热点代码探测技术,通过计数器找到最具有编译价值的代码,触发即时编译器(JIT)或栈上替换。
- BEA公司的JRockit:专注于服务器端应用,内部不包含解释器,全部代码都靠即时编译器编译执行,号称世界上最快的Java虚拟机。
- IBM公司的J9:市场定位与Hotspot接近,服务端、桌面、嵌入式都有应用,若部署在IBM自己的产品上,号称是世界上最快的虚拟机。该虚拟机于2017年正式对外发布,名字为OpenJ9,并交给Eclipse基金会打理。
曾经的三分天下,现在其二已被Oracle收购,不得不感叹,钞能力才是最终王者。
Sun Classic VM(始祖)
1996年1月23日,Sun公司发布JDK1.0,Java语言首次拥有了商用的正式运行环境,它就是Classic VM。这是第一款商用的虚拟机,是JVM界的始祖。在JDK 1.2及之前,用户用Classic虚拟机执行java-version命令,将会看到类似下 面这行的输出:
java version “1.2.2” Classic VM (build JDK-1.2.2-001, green threads, sunwjit)
在2002年年发布的jdk1.4后被完全淘汰,不见其踪影。
这款虚拟机只能使用纯解释器方式来执行Java代码,如果要使用JIT编译器(Just In Time 即时编译器),就必须进行外挂。但是呢,如果外挂了JIT,那么就完全接管了解释器的工作,那就不能称作为Classic VM了。
这个阶段的虚拟机即使外挂了JIT编译器输出本地代码,执行效率也和传统的C/C++程序有很大差距,Java语言很慢的形象就是在这个时候开始在用户心中建立起来的。
Exact VM(牛刀小试)
为了解决Sun Classic VM的慢,1998年在JDK 1.2发布时,曾在Solaris平台(Sun基于Unix分支自研的操作系统)上发布过一款名为Exact VM的虚拟机,是现代化高性能虚拟机的雏形,如热点探测、两级即时编译器、编译器与解释器混合工作模式等。
这块虚拟机只在Solaris平台牛刀小试,并未大规模使用,后被HotSpot取代。
HotSpot VM(武林盟主)
这是一个目前使用范围最广的Java虚拟机,它是Oracle JDK和OpenJDK的默认JVM,是聊天时没有特殊指定时的缺省JVM。
HotSpot VM正如其名,它的热点代码探测能力可以通过执行计数器找出最具有编译价值的代码,然后通知JIT编译器以方法为单位进行编译。这样子可以做到:如果某方法被频繁调用,将会触发标准编译和OSR(栈上替换)编译动作,编译器和解释器协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无须等待本地代码输出才能执行程序,即时编译的时间压力也相对减小,这样有助于引入更多的代码优化技术。
如果说综合表现,HotSpot VM可能最佳的虚拟机,它即可应用在资源相对充裕的Serve端,也可用桌面端,可谓通吃。2008年,Oracle收购BEA,得到了JRockit虚拟机;随后Oracle又收购了Sun,得到了Java和HotSpot虚拟机。JRockit和HotSpot都遵循JVM规范抽象只是是侧重点不同,Oracle最终决定将二者整合(合并),且名称仍叫HotSpot。
- 2011年发布JDK 7,完成初步整合:方法区从永久代里分离出来。
- 之前的JDK版本,常量池在方法区里,方法区在永久代里。7版本后分离出来了(但都在堆里)。
- 2014年发布JDK 8,基本完成整合:废弃永久代PermGen,改用元空间。
- JRockit没有永久代,IBM的J9也没有永久代。
JRockit VM(被Oracle收购)
JRockit层隶属于BEA公司,美国NASDAQ上市公司,其中间件市场份额一度比IBM 还要高,2008年初被Oracle 收购。
被Oracle后,同HotSpot合并后取名为HotSpot,从此彻底“销声匿迹”。
J9 VM(天下第二)
大名鼎鼎的IBM的J9,和JRockit有很多相似的地方。在IBM自己的机器上号称世界上最快的JVM虚拟机。IBM J9 VM并不是IBM公司唯一的Java虚拟机,不过是目前其主力发展的Java虚拟机。
与BEA JRockit专注于服务器端应用不同,IBM J9的市场定位与Sun HotSpot比较接近市场定位和HotSpot基本一样,实力竞品。
2017年,IBM发布了开源版本的J9 VM,命名为OpenJ9,并交给Eclipse基金会管理,所以也称为Eclipse OpenJ9。
Azul VM(性能中的战斗机)
Azul VM是与特定硬件平台绑定、软硬件配合的专有虚拟机,所以针对HotSpot做了大量改进,性能非常之高。但是:它只能运行在自己的系统以及硬件平台上。
Zing VM(通用版Azul VM)
Azul VM的性能非常高,但只能运行在特定的平台上,不能运行在普通的x86平台。
2010年,Azul System公司方向一转,开始从硬件转向软件,在Azul VM的基础上自研,研发出了可以用在通用的Linux/x86-64平台的Zing VM,主打低延迟、高实时服务器端JDK市场,性能号称接近于Azul VM。提供著名的“ReadyNow”能力,参考文档:https://www.azul.com/products/components/readynow。
但是,Zing VM 不开源,是收费的,并且还很贵很贵。要知道Azul是家商业化的公司,是要挣钱的呀。这不,在油管我就看到了Azul的广告:
Liquid VM(JRockit的虚拟化版本)
Liquid VM是JRockit VM 的虚拟化版本,可以在没有标准操作系统的虚拟机管理程序上运行,允许Java 应用程序直接在虚拟化硬件上运行。
Liquid是BEA公司的产品,2008年后也隶属于Oracle了,参考文档:https://docs.oracle.com/cd/E11035_01/wloc10/lvm/index.html。
Taobao VM(国产虚拟机)
Tobao VM,又名阿里JVM。早在2012年,Taobao VM已有一定名气,那会还有个官网:jvm.taobao.org,现已不能访问了。阿里巴巴作为国内Java最大应用商,应用集群规模达十几万甚至几十万,因此自研JVM很有意义。
Taobao VM的特点:在阿里产品上性能高,硬件严重依赖Intel的cpu,损失了兼容性,提高了性能。至于使用了什么技术、什么方式提升了性能,其实咱也不必关心。
为什么现在不见Taobao VM?销声匿迹了?是的,因为有了更具产品化的Alibaba Dragonwell这个产品替代了,使用和推广起来更加方便:待替换,替换成说JDK的那篇文章。
Graal VM
一款号称Run Programs Faster Anywhere,与1995年Java面世时的口号Write once, Run anywhere遥相呼应。GraalVM是Oracle开源的一款通用虚拟机产品,官方称之为 Universal GraalVM,是新一代的通用多语言高性能虚拟机。能执行各类高性能与互操作性任务,在无需额外开销的前提下允许用户构建多语言应用程序。
GraalVM支持大量的语言,包括:
- 基于JVM的语言(例如Java、Scala、Groovy、Kotlin、Clojure等)。
- 基于 LLVM 的语言(例如 C、C++等)。
- 动态语言(例如 JavaScript、Ruby、Python、R等)。
如果说HotSpot有一天真的被取代,大概率是Graal VM。但这Java的软件生态没有丝毫变化,也许依旧Oracle一家独大。
除以上之外,还有很多JVM作品:
- Microsoft JVM:微软早在IE3浏览器中支持Java Applets并自研了Microsoft JVM,直到1997年遭到Sun公司起诉才放弃,从而windows都安装的HotSpot。直到2021年5月份,Microsoft基于OpenJDK重新带来了其产品化的JDK产品,内置其自研的JVM。
- Apache Harmony:https://harmony.apache.org,Java的世界哪离开得了Apache,曾在JDK 1.5、1.6时期Apache也来参和一脚,这款VM是IBM和Intel联合开发的开源JVM,后遭到Sun公司的抵制不给颁发JCP认证,无奈2011年黯然退场。
- Dalvik JVM:谷歌开发,应用于Android系统。它只能称作虚拟机, 并不能称为Java虚拟机,因为并未遵循规范。此VM从Android 5.0时被ART VM替换。
- Embedded VM:也叫KVM千字节虚拟机,应用于移动领域。Sun公司进军嵌入式领域的虚拟机,用于手机、Pad、汽车等领域,这就是“大名鼎鼎”的J2ME。
总结
这么多虚拟机,我们该如何学习?笔者的经验是,比较深入的了解学习HotSpot足矣。当然,其它虚拟机、发展史也需要基本的了解,这是茶余饭后的谈资,是专业素养的体现。
最后,再回头在看看文首提到的三个问题,你有答案了吗?