丹丹学妹哭着对我说:Java感觉不愿意和我作朋友呢,怎么离她近一些(Java发展史,虚拟机发展史,java编译方式)?

【番外】: 学妹和我打赌,我回答出她的一个问题,她就让我问她一个私人问题~,那让我开始!!!!!!

  • 学妹:java技术体系包括了几个组成部分呀?
    我:可以看成5个部分呢,给你一个图自己看吧,太简单了呢~
    丹丹学妹哭着对我说:Java感觉不愿意和我作朋友呢,怎么离她近一些(Java发展史,虚拟机发展史,java编译方式)?_第1张图片
  • 学妹:javaME、SE、EE分别是什么呀?
    我清了清嗓子,准备给学妹解惑:
    ①、ME是支持Java程序在移动终端上的平台,JDK6之前叫J2ME,注意:Android可不属于JavaME;
    ②、SE是面向桌面级应用的Java平台,提供了完整的Java核心API,JDK6之前被称为J2SE;
    ③、EE支持使用多层架构的企业应用,JDK6之前被称为J2EE,JDK10之后被Oracle抛弃了,捐赠给了Eclipse基金会管理。
  • 学妹:都说JDK7版本是第一个里程碑版本,为什么这么说呀?
    我挠了挠头,感觉这个问题有点为难我:其实这个版本出现了很多项目;比如:
    ①、Lambda表达式项目(其实这里本来是想JDK7完成的,但是最后实际是在JDK8完成,并且在JDK8移除了HotSpot的永久代);
    ②、动态语言支持等,毕竟Java是静态语言,但可为其他运行在Java虚拟机上的动态语言提供支持;
  • 学妹:Java语言是属于哪家公司所有呀?
    当师妹问到这个问题,我抠了抠脚,严肃的告诉她:Java语言本身不属于任何公司所有,它由JCP组织进行管理,并且要注意我们以前说的Sun公司已经在09年被Oracle收购啦,中间件企业BEAE公司也已经被Oracle收购啦,所以Oracle公司是超级厉害的~

  • 学妹:师哥能给我讲一讲Java虚拟机嘛,就大致说一说就行,让我有个思路就好啦?
    我挠了挠胳肢窝,感觉好烦哦,但是作为师兄又不能不说明白,那让我理一下思路,和你说一说吧~
    其实从1996年初Sun发布的JDK1.0包含的Sun Classic虚拟机到今天,曾经涌现、湮灭过许多或经典,或优秀,或有特色,或有争议的虚拟机实现的,让我们从虚拟机始祖说起吧!

①、虚拟机始祖:SunClassic/Exact VM

  • SUN Classic VM:是一款解释型的java字节码执行引擎
    • java虚拟机分为两类执行引擎
      • ⅰ、 解释型: 一行一行执行代码,类似于javascript、python这类解释型的编程语言;
      • ⅱ、 及时编译(Just-In-Time) 执行引擎: 将字节码中的热点代码编译成机器码,并且将机器码缓存到方法区的代码缓存区
  • Sun Classic VM诞生于java1.0(1996年),是世界上第一款商用Java虚拟机,在jdk1.4(2002年)后被完全淘汰!;
  • Sun Classic VM内部只提供解释器,使用JIT编译器需要外挂,并且一旦使用JIT就会导致解释器不能执行;
  • sadd在《深入理解java虚拟机》中提到过:1996年1月23日,Sun发布JDK 1.0,Java语言首次拥有了商用的正式运行环境,这个JDK中所带的 虚拟机就是Classic VM。这款虚拟机只能使用纯解释器方式来执行Java代码,如果要使用即时编译器那 就必须进行外挂,但是假如外挂了即时编译器的话,即时编译器就会完全接管虚拟机的执行系统,解释器便不能再工作了。解释器不能工作会带来什么影响呢?
    1124由于解释器和编译器不能配合工作,这就意味着如果要使用编译执行,编译 器就不得不对每一个方法、每一行代码都进行编译,而无论它们执行的频率是否具有编译的价值。基 于程序响应时间的压力,这些编译器根本不敢应用编译耗时稍高的优化技术,因此这个阶段的虚拟机 虽然用了即时编译器输出本地代码,其执行效率也和传统的C/C++程序有很大差距,“Java语言很慢”的 印象就是在这阶段开始在用户心中树立起来的。
    1124Sun的虚拟机团队努力去解决Classic虚拟机所面临的各种问题,提升运行效率,在JDK 1.2时,曾 在Solaris平台上发布过一款名为Exact VM的虚拟机,它的编译执行系统已经具备现代高性能虚拟机雏 形,如热点探测、两级即时编译器、编译器与解释器混合工作模式等。
  • Exact VM:诞生于jdk1.2,主要目的是解决解释型引擎执行效率低的问题,也是现代高性能虚拟机的雏形
  • Exact VM:只在Solaris平台上使用,还没在其它平台上应用就被HotSpot虚拟机替换;
  • sadd在《深入理解java虚拟机》中提到过:Exact VM因使用准确式内存管理(Exact Memory Management,也可以叫Non-Conservative/Accurate Memory Management)而得名。
    1124准确式内存管理是指虚拟机可以知道内存中某个位 置的数据具体是什么类型。譬如内存中有一个32bit的整数123456,虚拟机将有能力分辨出它到底是一 个指向了123456的内存地址的引用类型还是一个数值为123456的整数,准确分辨出哪些内存是引用类型,这也是在垃圾收集时准确判断堆上的数据是否还可能被使用的前提。
    sadd由于使用了准确式内存管理,Exact VM可以抛弃掉以前Classic VM基于句柄(Handle)的对象查找方式(原因是垃圾收集后对象将可能会被移动位置,如果地址为123456的对象移动到654321,在没有明确信息表明内存中哪些数据是引用类型的前提下,那虚拟机肯定是不敢把内存中所有为123456的值改成654321的,所以要使用句柄来保持引用值的稳定),这样每次定位对象都少了一次间接查找的开销,显著提升执行性能。
    sadd虽然Exact VM的技术相对Classic VM来说先进很多,但是英雄气短,没怎么应用就被HotSpot淘汰了,相反Classic VM的生命周期则要长不少,它在JDK1.2之前是JDK中唯一的虚拟机;JDK1.2时,与HotSpot VM并存,是默认的虚拟机;JDK1.3时,HotSpot成为默认虚拟机。直到JDK1.4, Classic VM退出了历史舞台~

②、武林盟主:HotSpot

  • HotSpot虚拟机:由Longview Technologies小公司设计,1997年,由Sun公司收购;2009年Sun被Oracle收购;
  • jdk1.3时HotSpot VM成为了默认的java虚拟机;
  • HotSpot虚拟机: 是一款及时编译器执行引擎;
  • HotSpot虚拟机:占据绝对的市场地位,从jdk1.3到现如今jdk14都是 Oracle JDK 和 OpenJDK中默认的虚拟机,也是目前使用范围最广的Java虚拟机,面试中问到的GC也都是HotSpot虚拟机的GC机制;
  • sadd在《深入理解java虚拟机》中提到过:相信所有Java程序员都听说过HotSpot虚拟机,它是Sun/OracleJDK和OpenJDK中的默认Java虚拟 机,也是目前使用范围最广的Java虚拟机。但不一定所有人都知道的是,这个在今天看起来“血统纯 正”的虚拟机在最初并非由Sun公司所开发,而是由一家名为“Longview Technologies”的小公司设计;甚至这个虚拟机最初并非是为Java语言而研发的,它来源于Strongtalk虚拟机,而这款虚拟机中相当多的技术又是来源于一款为支持Self语言实现“达到C语言50%以上的执行效率”的目标而设计的Self虚拟机,最终甚至可以追溯到20世纪80年代中期开发的Berkeley Smalltalk上。Sun公司注意到这款虚拟机在即时编译等多个方面有着优秀的理念和实际成果,在1997年收购了Longview Technologies公司,从而获得了 HotSpot虚拟机
    saddHotSpot既继承了Sun之前两款商用虚拟机的优点(如:EaxtVM),也有许多自己新的技术优势,如它名称中的HotSpot指的就是它的热点代码探测技术(这里的描写带有“历史由胜 利者书写”的味道,其实HotSpot与Exact虚拟机基本上是同时期的独立产品,HotSpot出现得还稍早一些,一开始HotSpot就是基于准确式内存管理的,而Exact VM之中也有与HotSpot几乎一样的热点探测技术,为了Exact VM和HotSpot VM哪个该成为Sun主要支持的虚拟机,在Sun公司内部还争吵过一场, HotSpot击败Exact并不能算技术上的胜利),HotSpot虚拟机的热点代码探测能力可以通过执行计数器找出最具有编译价值的代码,然后通知即时编译器以方法为单位进行编译。如果一个方法被频繁调用,或方法中有效循环次数很多,将会分别触发标准即时编译和栈上替换编译(On-Stack Replacement,OSR)行为。通过编译器与解释器恰当地协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无须等待本地代码输出才能执行程序,即时编译的时间压力也相对减小,这样有助于引入更复杂的代码优化技术,输出质量更高的本地代码。
    sadd2006年,Sun陆续将SunJDK的各个部分在GPLv2协议下开放了源码,形成了Open-JDK项目,其中 当然也包括HotSpot虚拟机。HotSpot从此成为Sun/OracleJDK和OpenJDK两个实现极度接近的JDK项目的共同虚拟机。Oracle收购Sun以后,建立了HotRockit项目来把原来BEA JRockit中的优秀特性融合到 HotSpot之中。到了2014年的JDK8时期,里面的HotSpot就已是两者融合的结果,HotSpot在这个过程里移除掉永久代,吸收了JRockit的Java Mission Control监控工具等功能。

③、天下第二:JRockit VM/ J9 VM

  • JRockit VM:由BEA公司开发,是真正意义的世界上最快的java虚拟机。2008年,BEA公司被Oracle收购。
  • JRockit专注于服务端应用,JRockit内部不包含解释器实现,全部代码都靠及时编译器(JIT)编译后执行。
  • Oracle收购了BEA后,想要整合JRockit到HotSpot虚拟机上。后由于两者架构相差很大,只是部分优秀内容被整合。
  • sadd在《深入理解java虚拟机》中提到过:如果说HotSpot是天下第一的武林盟主,那曾经与HotSpot并称“三 大商业Java虚拟机”的另外两位,毫无疑问就该是天下第二了,它们分别是BEA System公司的JRockit与 IBM公司的IBM J9。
    saddJRockit虚拟机曾经号称是“世界上速度最快的Java虚拟机”(广告词,IBM J9虚拟机也这样宣传过,总体上三大虚拟机的性能是交替上升的),它是BEA在2002年从Appeal Virtual Machines公司收购获得的Java虚拟机。BEA将其发展为一款专门为服务器硬件和服务端应用场景高度优化的虚拟机,由于专注于服务端应用,它可以不太关注于程序启动速度,因此JRockit内部不包含解释器实现,全部代码都靠即时编译器编译后执行。除此之外,JRockit的垃圾收集器和Java Mission Control故障处理套件等部分的实现,在当时众多的Java虚拟机中也处于领先水平。JRockit随着BEA被Oracle收购,现已不再继续发展,永远停留在R28版本,这是JDK6版JRockit的代号。
  • IBM的J9全称:IBM Technology for Java Virtual Machine,简称IT4J,内部代号J9;
  • J9的市场定位与HotSpot接近,服务器端、桌面应用、嵌入式等多用途VM;
  • J9是目前由影响力的三大商业虚拟机之一,2017年IBM发布了开源J9 VM,命名为OpenJ9,交给Eclipse基金会管理,也称Eclipse OpenJ9;
  • sadd在《深入理解java虚拟机》中提到过:IBM J9虚拟机并不是IBM公司唯一的Java虚拟机,不过目前IBM主力发展无疑就是J9。J9这个名字最初只是内部开发代号而已,开始选定的正式名称是“IBM Technology for Java Virtual Machine”,简称IT4J,但这个名字太拗口,接受程度远不如J9。J9虚拟机最初是由IBM Ottawa实验室的一个 SmallTalk虚拟机项目扩展而来,当时这个虚拟机有一个Bug是因为8KB常量值定义错误引起,工程师们花了很长时间终于发现并解决了这个错误,此后这个版本的虚拟机就被称为K8,后来由其扩展而来、 支持Java语言的虚拟机就被命名为J9。与BEA JRockit只专注于服务端应用不同,IBM J9虚拟机的市场定位与HotSpot比较接近,它是一款在设计上全面考虑服务端、桌面应用,再到嵌入式的多用途虚拟机,开发J9的目的是作为IBM公司各种Java产品的执行平台,在和IBM产品(如IBM WebSphere等)搭配以及在IBM AIX和z/OS这些平台上部署Java应用
    saddJIBM J9直至今天仍旧非常活跃,IBM J9虚拟机的职责分离与模块化做得比HotSpot更优秀,由J9 虚拟机中抽象封装出来的核心组件库(包括垃圾收集器、即时编译器、诊断监控子系统等)就单独构 成了IBM OMR项目,可以在其他语言平台如Ruby、Python中快速组装成相应的功能。从2016年起, IBM逐步将OMR项目和J9虚拟机进行开源,完全开源后便将它们捐献给了Eclipse基金会管理,并重新命名为Eclipse OMR和OpenJ9。如果为了学习虚拟机技术而去阅读源码,更加模块化的OpenJ9代码 其实是比HotSpot更好的选择。如果为了使用Java虚拟机时多一种选择,那可以通过AdoptOpenJDK来 获得采用OpenJ9搭配上OpenJDK其他类库组成的完整JDK。
    sadd除BEA和IBM公司外,其他一些大公司也号称有自己的专属JDK和虚拟机,但是它们要么是通过 从Sun/Oracle公司购买版权的方式获得的(如HP、SAP等),要么是基于OpenJDK项目改进而来的 (如阿里巴巴、Twitter等),都并非自己独立开发。

③、挑战者:Apache Harmony/Google Dalvik VM

  • Apache Harmony由IBM和Intel联合开发的一款开源java,后IBM抨击Sun公司不开源java;
  • IBM希望Apache Harmony成为java的规范,于是Sun公司开源了java并命名为OpenJDK;
  • 并且坚决不让Apache Harmony获得JCP认证,最终2011年Apache Harmony退役,IBM转而参与OpenJDK;
  • Apache Harmony的java类库被Android SDK使用;
  • sadd在《深入理解java虚拟机》中提到过:Apache Harmony是一个Apache软件基金会旗下以Apache License协议开源的实际兼容于JDK 5和 JDK 6的Java程序运行平台,它含有自己的虚拟机和Java类库API,用户可以在上面运行Eclipse、 Tomcat、Maven等常用的Java程序。但是,它并没有通过TCK认证,所以我们不得不用一长串冗长拗 口的语言来介绍它,而不能用一句“Apache的JDK”或者“Apache的Java虚拟机”来直接代指。
    sadd如果一个公司要宣称自己的运行平台“兼容于Java技术体系”,那该运行平台就必须要通过 TCK(Technology Compatibility Kit)的兼容性测试,Apache基金会曾要求当时的Sun公司提供TCK的 使用授权,但是一直遭到各种理由的拖延和搪塞,直到Oracle收购了Sun公司之后,双方关系越闹越僵,最终导致Apache基金会愤然退出JCP组织,这是Java社区有史以来最严重的分裂事件之一。
    sadd当Sun公司把自家的JDK开源形成OpenJDK项目之后,Apache Harmony开源的优势被极大地抵消,以至于连Harmony项目的最大参与者IBM公司也宣布辞去Harmony项目管理主席的职位,转而参与OpenJDK的开发。虽然Harmony没有真正地被大规模商业运用过,但是它的许多代码(主要是Java 类库部分的代码)被吸纳进IBM的JDK 7实现以及Google Android SDK之中,尤其是对Android的发展起了很大推动作用。
  • 说到Android,这个时下最热门的移动数码设备平台在最近十年所取得的成果已经远远超越了Java ME在过去二十多年所获得的成果,Android让Java语言真正走进了移动数码设备领域,只是走得并非 Sun公司原本想象的那一条路。
  • sadd在《深入理解java虚拟机》中提到过:Dalvik虚拟机曾经是Android平台的核心组成部分之一,它的名字来源于冰岛一个名为Dalvik的小渔村。Dalvik虚拟机并不是一个Java虚拟机,它没有遵循《Java虚拟机规范》,不能直接执行Java的 Class文件,使用寄存器架构而不是Java虚拟机中常见的栈架构。但是它与Java却又有着千丝万缕的联系,它执行的DEX(Dalvik Executable)文件可以通过Class文件转化而来,使用Java语法编写应用程序,可以直接使用绝大部分的Java API等。在Android发展的早期,Dalvik虚拟机随着Android的成功迅速流行,在Android 2.2中开始提供即时编译器实现,执行性能又有了进一步提高。不过到了Android 4.4时代,支持提前编译(Ahead of Time Compilation,AOT)的ART虚拟机迅速崛起,在当时性能还不算特别强大的移动设备上,提前编译要比即时编译更容易获得高性能,所以在Android 5.0里ART就全面代替了Dalvik虚拟机

④、Microsoft JVM

  • 微软为了在IE3浏览器中支持Java Applets,开发了Microsoft JVM;
  • Microsoft JVM只能在windows平台下运行,但确实是当时windows平台上性能最好的java虚拟机;
  • 1997年,Sun指控微软侵犯商标成功,微软赔了Sun公司很多前,微软在windows XP SP3中抹除了其VM。现在windows安装的jdk都是HotSpot虚拟机;
  • sadd在《深入理解java虚拟机》中提到过:在Java语言诞生的初期(1996年~1998年,以JDK1.2发布之前为分界),它的主要应用之一是在 浏览器中运行Java Applets程序,微软为了在Internet Explorer 3浏览器中支持Java Applets应用而开发了 自己的Java虚拟机,虽然这款虚拟机只有Windows平台的版本,“一次编译,到处运行”根本无从谈起, 但却是当时Windows系统下性能最好的Java虚拟机,它在1997年和1998年连续获得了《PC Magazine》 杂志的“编辑选择奖”。但是好景不长,在1997年10月,Sun公司正式以侵犯商标、不正当竞争等罪名控 告微软,在随后对微软公司的垄断调查之中,这款虚拟机也曾作为证据之一被呈送法庭。官司的结果 是微软向Sun公司(最终微软因垄断赔偿给Sun公司的总金额高达10亿美元)赔偿2000万美金,承诺终止其Java虚拟机的发展,并逐步在产品中移除Java虚拟机相关功能。而最令人感到讽刺的是,到后来在 Windows XP SP3中Java虚拟机被完全抹去的时候,Sun公司却又到处登报希望微软不要这样做。 Windows XP高级产品经理Jim Cullinan称:“我们花费了三年的时间和Sun公司打官司,当时他们试图阻止我们在Windows中支持Java,现在我们这样做了,可他们又在抱怨,这太具有讽刺意味了。”

⑤、Taobao JVM

  • Taobao JVM基于OpenJDK开发了自己定制版本的AlibabaJDK。简称AJDK。主要想解决高并发、高可用、分布式的复合问题。
  • 特点:将生命周期较长的java对象从堆中移到堆外,并且GC不能管理GCIH(GC不用管理的堆)内部的java对象。以达到降低GC的回收频率和提升GC的回收效率的目的。
  • GCIH:还能再多个java虚拟机进程中实现共享对象。
  • 使用crc32指令实现JVM intrinsic降低JNI的调用开销
  • PMU hardware的java Profiling tool和诊断协助功能;
  • 针对大数据场景的ZemGC
  • TaobaoVM应用在阿里产品上性能高,硬件严重依赖intel的cpu,损失了兼容性,提高了性能
  • 目前已经在淘宝、天猫上线,把Oracle官方的JVM全部替换。

⑥、未来可能的趋势:新一代即时编译器Graal VM

  • sadd在《深入理解java虚拟机》中提到过:Hotspot虚拟机中有两个即时编译器,分别是编译耗时段但输出代码优化程度较低的客户端编译器(简称为C1)以及编译耗时较长但输出代码优化质量也较高的服务端编译器(简称为C2),通常它们会在分层编译机制下与解释器互相配合来共同构成Hotspot虚拟机的执行子系统。
    sadd自JDK 10起,HotSpot中又加入了一个全新的即时编译器:Graal编译器,看名字就可以联想到它是来自于前一节提到的Graal VM。Graal编译器是以C2编译器替代者的身份登场的。C2的历史已经非常长了,可以追溯到Cliff Click大神读博士期间的作品,这个由C++写成的编译器尽管目前依然效果拔 群,但已经复杂到连Cliff Click本人都不愿意继续维护的程度。而Graal编译器本身就是由Java语言写成,实现时又刻意与C2采用了同一种名为“Sea-of-Nodes”的高级中间表示(High IR)形式,使其能够 更容易借鉴C2的优点。Graal编译器比C2编译器晚了足足二十年面世,有着极其充沛的后发优势,在保持输出相近质量的编译代码的同时,开发效率和扩展性上都要显著优于C2编译器,这决定了C2编译器中优秀的代码优化技术可以轻易地移植到Graal编译器上,但是反过来Graal编译器中行之有效的优化在 C2编译器里实现起来则异常艰难。这种情况下,Graal的编译效果短短几年间迅速追平了C2,甚至某些 测试项中开始逐渐反超C2编译器。Graal能够做比C2更加复杂的优化,如“部分逃逸分析”(Partial Escape Analysis),也拥有比C2更容易使用激进预测性优化(Aggressive Speculative Optimization)的策略,支持自定义的预测性假设等
    -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler 参数来启用Graal编译器
  • 2018年4月,Oracle Labs公开了Graal VM,号称“Run Programs Faster Anywhere”
  • Graal VM是在HotSpot VM基础上增强而成的跨语言全栈虚拟机,可以作为“任何语言”的运行平台使用。语言包括:Java、Scala、Groovy、Kotlin;C、C++、Javascript、Ruby、Python、R 等;
    丹丹学妹哭着对我说:Java感觉不愿意和我作朋友呢,怎么离她近一些(Java发展史,虚拟机发展史,java编译方式)?_第2张图片
  • 它支持不同语言中混合使用对方的接口和对象,支持这些语言使用已经编写号的本地库文件;
  • 工作原理: 是将这些语言的源码或源代码编译后的中间格式,通过解释器转换为能被Graal VM接受的中间表示。Graal VM提供Truffle工具集快速构建面向一种新语言的解释器在运行时还能进行编译优化,获得比原生编译器更优秀的执行效率。
  • sadd在《深入理解java虚拟机》中提到过:网上每隔一段时间就能见到几条“未来X语言将会取代Java”的新闻,此处“X”可以用Kotlin、 Golang、Dart、JavaScript、Python等各种编程语言来代入。这大概就是长期占据编程语言榜单第一位的烦恼,天下第一总避免不了挑战者相伴。
    sadd如果Java有拟人化的思维,它应该从来没有惧怕过被哪一门语言所取代,Java“天下第一”的底气不在于语法多么先进好用,而是来自它庞大的用户群和极其成熟的软件生态,这在朝夕之间难以撼动。 不过,既然有那么多新、旧编程语言的兴起躁动,说明必然有其需求动力所在,譬如互联网之于 JavaScript、人工智能之于Python,微服务风潮之于Golang等。大家都清楚不太可能有哪门语言能在每 一个领域都尽占优势,Java已是距离这个目标最接近的选项,但若“天下第一”还要百尺竿头更进一步 的话,似乎就只能忘掉Java语言本身,踏入无招胜有招的境界。
    sadd2018年4月,Oracle Labs新公开了一项黑科技:Graal VM,如图1-4所示,从它的口号“Run Programs Faster Anywhere”就能感觉到一颗蓬勃的野心,这句话显然是与1995年Java刚诞生时的“Write Once,Run Anywhere”在遥相呼应。
    saddGraal VM被官方称为“Universal VM”和“Polyglot VM”,这是一个在HotSpot虚拟机基础上增强而成 的跨语言全栈虚拟机,可以作为“任何语言”的运行平台使用,这里“任何语言”包括了Java、Scala、 Groovy、Kotlin等基于Java虚拟机之上的语言,还包括了C、C++、Rust等基于LLVM的语言,同时支 持其他像JavaScript、Ruby、Python和R语言等。Graal VM可以无额外开销地混合使用这些编程语言, 支持不同语言中混用对方的接口和对象,也能够支持这些语言使用已经编写好的本地库文件。
      Graal VM的基本工作原理是将这些语言的源代码(例如JavaScript)或源代码编译后的中间格式 (例如LLVM字节码)通过解释器转换为能被Graal VM接受的中间表示(Intermediate Representation, IR),譬如设计一个解释器专门对LLVM输出的字节码进行转换来支持C和C++语言,这个过程称为程 序特化(Specialized,也常被称为Partial Evaluation)。Graal VM提供了Truffle工具集来快速构建面向一种新语言的解释器,并用它构建了一个称为Sulong的高性能LLVM字节码解释器。
    sadd从更严格的角度来看,Graal VM才是真正意义上与物理计算机相对应的高级语言虚拟机,理由是 它与物理硬件的指令集一样,做到了只与机器特性相关而不与某种高级语言特性相关。Oracle Labs的 研究总监Thomas Wuerthinger在接受InfoQ采访时谈到:“随着GraalVM 1.0的发布,我们已经证明了拥 有高性能的多语言虚拟机是可能的,并且实现这个目标的最佳方式不是通过类似Java虚拟机和微软 CLR那样带有语言特性的字节码。”对于一些本来就不以速度见长的语言运行环境,由于Graal VM 本身能够对输入的中间表示进行自动优化,在运行时还能进行即时编译优化,因此使用Graal VM实现往往能够获得比原生编译器更优秀的执行效率,譬如Graal.js要优于Node.js[3],Graal.Python要优于 CPtyhon[4],TruffleRuby要优于Ruby MRI,FastR要优于R语言等。
    sadd对Java而言,Graal VM本来就是在HotSpot基础上诞生的,天生就可作为一套完整的符合Java SE 8 标准的Java虚拟机来使用。它和标准的HotSpot的差异主要在即时编译器上,其执行效率、编译质量目前与标准版的HotSpot相比也是互有胜负。但现在Oracle Labs和美国大学里面的研究院所做的最新即时编译技术的研究全部都迁移至基于Graal VM之上进行了,其发展潜力令人期待。如果Java语言或者 HotSpot虚拟机真的有被取代的一天,那从现在看来Graal VM是希望最大的一个候选项,这场革命很可能会在Java使用者没有明显感觉的情况下悄然而来,Java世界所有的软件生态都没有发生丝毫变化, 但天下第一的位置已经悄然更迭。

我长舒一口气,学妹你可明白了??如果还不明白,那你真对不起我了~

  • 学妹:明白是明白了,那什么叫提前编译(AOT)呀,我看老版本JDK是不支持的?
    我清了清嗓子,准备给学妹解惑,说到提前编译,我暗自摇头,又要浪费我的手指头动一动了,我在这里就简单说一说吧,具体的我们后面深入交流再~

Java一共有三种编译方式:前端编译 、后端编译(JIT编译) 、 静态提前编译(AOT编译)

  • 学妹你首先要清楚,Java程序代码需要编译后才能在虚拟机中运行,编译涉及到非常多的知识层面:编译原理、语言规范、虚拟机规范、本地机器码优化等;了解编译过程有利于了解整个Java运行机制,不仅可以使得我们编写出更优秀的代码,而且还可以使得在JVM调优时更得心应手。

①、前端编译

  • Java源码文件(.java)编译成Class文件(.class)的过程,说白了就是把满足Java语言规范的程序转化为满足JVM规范所要求格式的功能;
  • 优点:
    • 这阶段的优化是指程序编码方面的;
    • 许多Java语法新特性(泛型、内部类等),是靠前端编译器实现的,而不是依赖虚拟机;
    • 编译成的Class文件可以直接给JVM解释器解释执行,省去编译时间,加快启动速度;
  • 缺点:
    • 对代码运行效率几乎没有任何优化措施;
    • 解释执行效率较低,所以需要结合下面的JIT编译;
  • 前端编译器:Oracle javac、Eclipse JDT中的增量式编译器(ECJ)等;

②、后端编译/即时(JIT)编译

  • 通过Java虚拟机(JVM)内置的即时编译器(Just In Time Compiler,JIT编译器):在运行时把Class文件字节码编译成本地机器码的过程;
  • 优点:
    • 过在运行时收集监控信息,把"热点代码"(Hot Spot Code)编译成与本地平台相关的机器码,并进行各种层次的优化;
    • 可以大大提高执行效率;
  • 缺点:
    • 收集监控信息影响程序运行;
    • 编译过程占用程序运行时间(如使得启动速度变慢);
    • 编译机器码占用内存;
  • JIT编译器: HotSpot虚拟机的C1、C2编译器等;
  • 另外,JIT编译速度及编译结果的优劣,是衡量一个JVM性能的很重要指标;所以对程序运行性能优化集中到这个阶段;也就是说可以对这个阶段进行JVM调优;

③、静态提前编译(Ahead Of Time,AOT编译)

  • 程序运行前,直接把Java源码文件(.java)编译成本地机器码的过程;
  • 优点:
    • 编译不占用运行时间,可以做一些较耗时的优化,并可加快程序启动;
    • 把编译的本地机器码保存磁盘,不占用内存,并可多次使用;
  • 缺点:
    • 因为Java语言的动态性(如反射)带来了额外的复杂性,影响了静态编译代码的质量;
    • 一般静态编译不如JIT编译的质量,这种方式用得比较少;
  • 静态提前编译器(AOT编译器):JAOTC、GCJ、Excelsior JET、ART (Android Runtime)等
  • 关于ART (Android Runtime)模式:ART虽然主要通过AOT编译支持Java的运行,但仍然带有解释器;

④、前端编译+JIT编译

  • 目前Java体系中主要还是采用前端编译+JIT编译的方式,如JDK中的HotSpot虚拟机。
  • 前端编译+JIT编译方式的运作过程大体如下:
    • 首先通过前端编译把符合Java语言规范的程序代码转化为满足JVM规范所要求Class格式
    • 然后程序启动时Class格式文件发挥作用,解释执行,省去编译时间,加快启动速度;
    • 针对Class解释执行效率低的问题,在运行中收集性能监控信息,得知 “热点代码”
    • JIT逐渐发挥作用,把越来越多的热点代码"编译优化成本地代码,提高执行效率

  • 到此就结束啦,如果丹丹师妹还想看别的,就给你推荐两篇博客吧,我给你讲的好多都是这篇中的讲到的:
    Java编译(一) Java三种编译方式:前端编译 JIT编译 AOT编译

你可能感兴趣的:(JVM)