当前位置: 首页 > 科技观察

除了HotSpot,你对JVM还了解什么?

时间:2023-03-20 12:51:26 科技观察

嗨,这是你的蝙蝠侠,坐稳并坚持住,然后开始开车。TitleLink专栏【方向盘】-基本功源码https://github.com/yourbatman/FXP-java-ee程序员专用网盘公益上线,注册送1G超小容量,帮你练减法https://wangpan.yourbatman.cnJava开发软件包(Mac)https://wangpan.yourbatman.cn/s/rEH0提取码:javakit女娲工程http://152.136.106.14:8761版本约定[JDK1.0-17]如何使用关于前言明白Java是跨平台语言吗?Java是编译语言还是解释语言?JDK、JRE和JVM有什么区别?这三个常见问题都绕不开一个关键词:JVM。每个Javaer都知道,可以说是又爱又恨,爱它难,恨它难。当然,本文并不是要“深入理解Java虚拟机”。JVM发展了这么多年,关于它的权威书籍、文章、视频也很多。很简单,问问自己这个问题:“除了HotSpot,你还了解JVM什么?”那我们就一起来了解一下JVM及相关产品的发展吧。从字面上看,Java虚拟机(JVM)是一种从未实际构建到硬件中的假想计算机。JVM运行编译到其虚构指令集中的程序,该指令集作为称为字节码的中间表示形式写入存储。在运行时,字节码必须从虚构的指令集转换为主机CPU的实际指令集。这可以由“解释器”即时完成。或者字节码可以完全编译和缓存以比通过解释器运行得更快,在一个称为即时(JIT)编译的过程中。几十年来,出现了许多JVM实现。到2022年,它们中的大多数已经消失。基础知识的老规矩,首先要为基础知识打好基础。什么是JVMJVM(JavaVirtualMachine),即Java虚拟机。它是Java程序的运行平台,是二进制字节码的运行环境。它有很多商业版本,其中最著名的是Oracle的正式版,也是JDK默认的HotSpot。JVM发展到今天,已经不仅仅是为了Java。它已成为一个跨语言平台。只要是符合规范的字节码文件,就可以执行。例如,Java是..JVM规范Java语言各个版本对应的虚拟机规范:JavaLanguageandVirtualMachineSpecifications。JVM是虚拟机,一般来说是一种标准规范。虚拟机的实现版本有很多,这就是本文要介绍的内容。JVM所在的位置JVM运行在操作系统之上,不直接与硬件交互。字节码文件运行在JVM上,从而实现了字节码的跨平台效果。从下图也可以得到一个解题思路:没有加一层解决不了的问题。如果有,则添加另一层。跨平台是如何实现的这里的跨平台不是指跨操作系统,而是指不同操作系统上的虚拟机帮你执行,屏蔽了底层的适配性。正所谓复杂性不会凭空消失,只是JVM帮你解决/屏蔽了这种复杂性。一图胜千言:编译器和解释器的区别解释器:直接执行用编程语言编写的指令的程序。编译器将源程序的每条语句编译成机器语言,并保存为二进制文件,这样计算机在运行时就可以直接用机器语言运行程序,速度非常快。编译器:将源代码转换(翻译)为“低级”语言的程序。解释器只是在程序执行的时候,把它一段一段地解释成机器语言供计算机执行,所以运行速度没有编译好的程序快。下面通过表格比较一下两者的详细区别:编译器解释器将高级指令转换为机器可理解的指令高级代码无需转换直接执行将程序作为一个整体进行翻译将程序逐条进行翻译生成中间代码或目标代码在没有中间代码的情况下编译后,创建一个可执行文件每次执行都需要解释编译器类型:本机编译器,交叉编译器,源到源编译器,单程编译器,增量编译器,源编译器解释器类型:字节码解释器线程代码解释器、抽象语法树解释器编译器语言:JavaScalaC/C++C#解释器语言:PHP、Python、Ruby、JSJVM发展历史1996年JDK1.0发布时,SunClassicVM发布。第一个商业虚拟机,纯粹的解释和执行。1997年JDK1.1发布时,虚拟机没有任何变化。1998年JDK1.2发布时,提供了ExactVM虚拟机,但仅限于Solaris平台。默认虚拟机仍然是SunClassicVM。Solaris系统是Sun开发的操作系统,是UNIX操作系统的派生版本之一。2000年发布JDK1.3时,默认虚拟机从SunClassicVM更改为著名的SunHotSoptVM。此时,SunClassicVM尚未作为备份删除。2002年JDK1.4发布时,SunHotSpotVM站稳了脚跟,一直是默认的。现在,SunClassicVM已经彻底退出了商业虚拟机的舞台。2003年,Scala正式发布,同年Groovy也加入了JVM阵营。2006年,也就是JDK6发布的同年,OpenJDK项目复工。从逻辑上讲,HotSoptVM到现在也成为了OpenJDK的默认虚拟机。2008年,甲骨文收购BEA,获得了JRockit虚拟机。JRockit专注于服务器端应用程序,内部不包含解析器实现。它号称是世界上最快的JVM。2009年甲骨文收购Sun,获得了Java商标和HotSpot虚拟机商标。2011年JDK7发布时,在JDK1.7u4中,首次引入了G1垃圾回收期。2014年,JDK8发布,用MetaSpace员工空间取代了PermGen永久代。2017年JDK9发布,G1成为HotSpot的默认GC。从此,CMS成为了历史。同年IBM的J9开源,形成了现在的0penJ9社区。在2018年AndroidJava侵权案中,谷歌共赔偿甲骨文88亿美元。同年,甲骨文宣布JavaEE成为历史名词,并将JDBC、JMS、Servlet捐赠给Eclipse基金会。2020、2021、2022三大商用虚拟机在甲骨文收购Sun之前,JVM虚拟机呈现出三足鼎立的局面,各有优势。它们是:Sun公司的Hotspot:说到虚拟机,如果没有特别说明,就是指HotSpot。这是官方的,纯正的血统。其特点/优势是:热代码检测技术,通过计数器找到编译价值最高的代码,触发即时编译器(JIT)或栈上替换。BEA的JRockit:专注于服务器端应用,内部不包含解释器,所有代码均由即时编译器编译执行。它被称为世界上最快的Java虚拟机。IBM的J9:市场定位接近Hotspot,应用在服务器、桌面、嵌入式。如果部署在IBM自己的产品上,它被称为世界上最快的虚拟机。该虚拟机于2017年正式发布,命名为OpenJ9,并移交给Eclipse基金会。以前是世界三分之一,现在第二已经被甲骨文收购了。不得不感叹,赚钱能力才是终极王道。SunClassicVM(始祖)1996年1月23日,Sun发布了JDK1.0,Java语言第一次有了商业化的正式运行环境,这就是ClassicVM。这是第一个商用虚拟机,也是JVM世界的鼻祖。在JDK1.2之前,如果用户使用Classic虚拟机执行java-version命令,他将看到类似于以下行的输出:javaversion“1.2.2”ClassicVM(buildJDK-1.2.2-001,greenthreads,sunwjit)在2002年jdk1.4发布后被彻底淘汰,从此销声匿迹。这个虚拟机只能使用纯解释器来执行Java代码。如果要使用JIT编译器(JustInTime即时编译器),就必须外挂。但是,如果外挂JIT,它将完全接管解释器的工作,不能称为经典VM。即使现阶段的虚拟机外挂了JIT编译器输出native代码,执行效率仍然远远落后于传统的C/C++程序。也正是在这个时候,慢速Java语言的形象开始在用户心目中建立起来。为了解决SunClassicVM速度慢的问题,ExactVM(Sun的小试)在1998年发布JDK1.2时,在Solaris平台(Sun基于Unix分支自主研发的操作系统)上发布了一款名为ExactVM的虚拟机。现代高性能虚拟机原型,如热点检测、两级即时编译器、编译器和解释器混合工作模式等。该虚拟机仅在Solaris平台上测试,未使用规模较大,后来被HotSpot取代。HotSpotVM(武林教主)是目前使用最广泛的Java虚拟机。是OracleJDK和OpenJDK默认的JVM,聊天的时候没有特别指定的时候就是默认的JVM。HotSpotVM顾名思义,它的热点代码检测能力可以通过执行计数器找出编译值最高的代码,然后通知JIT编译器以方法为单位进行编译。可以这样实现:如果一个方法被频繁调用,就会触发标准编译和OSR(on-stackreplacement)编译动作。编译器和解释器协同工作以优化程序响应时间和最佳执行性能。实现了一个平衡,不需要等待native代码输出来执行程序,相对减少了即时编译的时间压力,有助于引入更多的代码优化技术。就整体性能而言,HotSpotVM可能是最好的虚拟机。可以用在资源比较丰富的服务器端,也可以用在桌面端。2008年,甲骨文收购BEA,得到JRockit虚拟机;然后Oracle收购了Sun,得到了Java和HotSpot虚拟机。JRockit和HotSpot都遵循JVM规范抽象,只是侧重点不同。甲骨文最终决定将两者整合(合并),名字还是叫HotSpot。2011年,JDK7发布,完成初步整合:方法区与永久代分离。在以前的JDK版本中,常量池在方法区,方法区在永久代。在版本7之后分离(但都在堆中)。2014年JDK8发布,基本完成整合:永久代PermGen被舍弃,改用元空间。JRockit没有永久代,IBM的J9也没有永久代。JRockitVM(被Oracle收购)JRockit层属于美国纳斯达克上市公司BEA。其中间件市场份额一度高于IBM,2008年初被甲骨文收购,被甲骨文收购后与HotSpot合并并命名为HotSpot,从此彻底“销声匿迹”。J9VM(世界第二)大名鼎鼎的IBM的J9与JRockit有很多相似之处。在IBM自己的机器上号称世界上最快的JVM虚拟机。IBMJ9VM并不是IBM唯一的Java虚拟机,但它是目前Java虚拟机的主要发展方向。与专注于服务器端应用的BEAJRockit不同,IBMJ9的市场定位与SunHotSpot比较接近,其市场定位与HotSpot基本一致,属于竞品。2017年,IBM发布了J9VM的开源版本,命名为OpenJ9,并交给EclipseFoundation进行管理,因此又被称为EclipseOpenJ9。AzulVM(fighterinperformance)AzulVM是一种专有的虚拟机,绑定特定的硬件平台,软硬件协同。因此HotSpot做了很多改进,性能非常高。But:它只能运行在自己的系统和硬件平台上。ZingVM(AzulVM的通用版本)AzulVM具有非常高的性能,但它只能运行在特定的平台上,不能运行在普通的x86平台上。2010年,AzulSystem转变方向,开始从硬件转向软件。在AzulVM的基础上,自研ZingVM,可在通用Linux/x86-64平台上使用,主打低延迟、高实时服务器端JDK市场,性能号称接近于AzulVM。提供著名的“ReadyNow”能力,参考文档:https://www.azul.com/products/components/readynow。不过ZingVM不是开源的,是收费的,而且很贵。要知道Azul是一家商业公司,要赚钱。这不,在YouTube上看到了Azul的广告:LiquidVM(JRockit的虚拟化版本)LiquidVM是JRockitVM的虚拟化版本,可以在没有标准操作系统的情况下运行在虚拟机管理程序上,让Java应用程序直接运行在虚拟化硬件上.Liquid是BEA的产品,从2008年开始隶属于Oracle。参考文档:https://docs.oracle.com/cd/E11035_01/wloc10/lvm/index.html。淘宝VM(国产虚拟机)TobaoVM,又称阿里JVM。早在2012年,淘宝VM就有了一定的知名度,当时有个官网:jvm.taobao.org,现在已经不能访问了。阿里巴巴作为国内最大的Java应用提供商,拥有几十万甚至几十万的应用集群,自研JVM意义重大。淘宝VM特点:阿里产品性能高,硬件严重依赖Intel的cpu,失去兼容性,提高性能。至于用什么技术,用什么方法提升性能,我们其实不需要关心。为什么现在没有淘宝VM?消失了?是的,因为已经换成更产品化的AlibabaDragonwell产品,使用和推广更方便:要换,换成关于JDK的文章。GraalVM被称为RunProgramsFasterAnywhere,这与1995年Java问世时的口号Writeonce,Runanywhere相呼应。GraalVM是Oracle开源的通用虚拟机产品。它的官方名称是UniversalGraalVM。它是新一代通用的多语言高性能虚拟机。它可以执行各种高性能和互操作性任务,允许用户在没有额外开销的情况下构建多语言应用程序。GraalVM支持大量语言,包括:基于JVM的语言(如Java、Scala、Groovy、Kotlin、Clojure等)。基于LLVM的语言(如C、C++等)。动态语言(例如JavaScript、Ruby、Python、R等)。如果有一天真的更换了HotSpot,很可能是GraalVM。但是Java的软件生态一点都没有变,或许甲骨文还是独一份。除了以上,还有很多JVM的作品:MicrosoftJVM:微软在IE3浏览器中支持JavaApplets,自己开发了MicrosoftJVM。到2021年5月,微软将带回基于OpenJDK的产品化JDK产品,内置自研JVM。还参与了JDK1.5和1.6。这个VM是IBM和Intel联合开发的开源JVM。遭到Sun的抵制,拒绝颁发JCP认证,只好于2011年退出。DalvikJVM:谷歌开发,应用于Android系统。只能叫虚拟机,不能叫Java虚拟机,因为不符合规范。此VM已被Android5.0中的ARTVM取代。嵌入式VM:又称KVM千字节虚拟机,应用于移动领域。Sun在嵌入式领域进军虚拟机,应用于手机、Pad、汽车等领域。这就是“大名鼎鼎”的J2ME。总结了这么多虚拟机,我们怎么学习呢?笔者的经验是,对HotSpot有更深入的了解就足够了。当然,其他的虚拟机和发展历史也需要有一个基本的了解。这是饭后闲聊,是专业素养的体现。最后,回头看看文章开头提到的三个问题。你有答案吗?