目录
一、开篇感言
二、正文
1.Java技术体系
1.1 Java技术体系介绍
1.2 JDK和JRE范围
1.3 Java主要产品线
1.4 Java发展史
1.5 Java虚拟机家族
对于Java开发程序员来说,对于JVM大都不会陌生。近来对JVM产生了浓厚的兴趣,拜读了周志明老师的《深入理解Java虚拟机》,学到了很多认知之外的知识。遂产生了梳理该书的主要知识点以及用通俗方式让大家更快更好的掌握认识到该书。
如果你对JVM还处于一知半解或者从未接触的情况,希望本栏目对你的个人提升能够有所帮助。如果你对JVM已经炉火纯青或者有所建树,希望对本栏目给予更多的指导和指正,以期帮助更多的人。
最后,以本书该章节的第一句话结束感言:世界上并没有完美的程序,但我们并不因此而沮丧,因为写程序本来就是一个不断追求完美的过程。
从广义上讲,Kotlin、Clojure、JRuby、Groovy等运行于Java虚拟机上的编程语言及其相关的程序都属于Java技术体系中的一员。
从传统意义上来看,JCP官方(Java Community Process,通称“Java社区”)所定义的Java技术体系包括了以下几个组成部分:Java程序设计语言、Java虚拟机、Class文件、Java类库、第三方Java类库。
Java类库API中的Java SE API子集和Java虚拟机这两部分统称为JRE(Java Runtime Environment),JRE是支持Java程序运行的标准环境。
Java程序设计语言、Java虚拟机、Java类库这三部分统称为JDK(Java Development Kit),JDK是用于支持Java程序开发的最小环境。
下图展示了Java技术体系所包括的内容,以及JDK和JRE所涵盖的范围。
名称 | 介绍 |
---|---|
Java Card | 支持Java小程序(Applets)运行在小内存设备(如智能卡)上的平台。 |
Java ME(Micro Edition) |
支持Java程序运行在移动终端(手机、PDA)上的平台,对Java API有所精简,并加入了移动终端的针对性支持。 JDK 6以前被称为J2ME。 |
Java SE(Standard Edition) | 支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API。 JDK 6以前被称为J2SE。 |
Java EE(Enterprise Edition) | 支持使用多层架构的企业应用(如ERP、MIS、CRM应用)的Java平台,除了提供Java SE API外,还对其做了大量有针对性的扩充(以javax.*作为包名)。 JDK 6以前被称为J2EE,在JDK 10以后被Oracle放弃,捐献给Eclipse基金会管理,此后被称为Jakarta EE。 |
1991年4月,由James Gosling博士领导的绿色计划(Green Project)开始启动,此计划最初的目标是开发一种能够在各种消费性电子产品(如机顶盒、冰箱、收音机等)上运行的程序架构。这个计划的产品就是Java语言的前身:Oak。
1995年5月23日,Oak语言改名为Java,并且在SunWorld大会上正式发布Java 1.0版本。
1996年1月23日,JDK 1.0发布,提供了一个纯解释执行的Java虚拟机实现(Sun Classic VM)。代表技术包括:Java虚拟机、Applet、AWT等。
1996年5月底,Sun于美国旧金山举行了首届JavaOne大会。
1997年2月19日,JDK 1.1发布,代表技术包括:JAR文件格式、JDBC、JavaBeans、RMI等。语法增强:内部类(Inner Class)、反射(Reflection)。
1999年4月8日,JDK 1.1一共发布了1.1.0至1.1.8这9个版本。从1.1.4以后,每个JDK版本都有一个属于自己的名字(工程代号),分别为:JDK 1.1.4-Sparkler(宝石)、JDK 1.1.5-Pumpkin(南瓜)、JDK 1.1.6-Abigail(阿比盖尔,女子名)、JDK 1.1.7-Brutus(布鲁图,古罗马政治家和将军)和JDK 1.1.8-Chelsea(切尔西,城市名)。
1998年12月4日,JDK 1.2-Playground(竞技场)发布,代表性技术:EJB、Java Plug-in、Java IDL、Swing等。Java技术体系拆分为三个方向:J2SE、J2EE和J2ME。Java虚拟机内置了JIT(Just In Time)即时编译器。在语言和API层面上,Java添加了strictfp关键字,Java类库添加了Collections集合类等。
1999年3月和7月,JDK 1.2.1和JDK 1.2.2两个小升级版本发布。
1999年4月27日,发布HotSpot虚拟机(JDK 1.3及之后所有JDK版本的默认Java虚拟机)。
2000年5月8日,JDK 1.3-Kestrel(美洲红隼)发布,Java类库:数学运算和新的Timer API。JNDI服务从扩展服务提升为平台级服务,使用CORBA IIOP来实现RMI的通信协议,提供了大量新的Java 2D API,并且新添加了JavaSound类库。
2001年5月17日,JDK 1.3.1-Ladybird(瓢虫)发布,此后JDK的主版本以动物命名,修正版本以昆虫作为工程代号。
2002年2月13日,JDK 1.4-Merlin(灰背隼)发布,是Java真正走向成熟的一个版本。新的技术特性:正则表达式、异常链、NIO、日志类、XML解析器和XSLT转换器等等。
2002年9月16日,JDK 1.4.1-Grasshopper(蚱蜢)发布。
2003年6月26日,JDK 1.4.2-Mantis(螳螂) 发布 。
2004年9月30日,JDK 5-Tiger(老虎)发布,语法特性:自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环(foreach循环)等。虚拟机和API层:改进了Java的内存模型(Java Memory Model,JMM)、提供了java.util.concurrent并发包等。此后JDK的版本号从“JDK 1.x”修改成了“JDK x”。
2006年11月13日的JavaOne大会上,Java正式开源,JDK各个部分陆续在GPL v2协议下公开了源码,并建立了OpenJDK组织对这些源码进行独立管理。OpenJDK几乎拥有了当时SunJDK 7的全部代码。
2006年12月11日,JDK 6-Mustang(野马)发布,语法特性:提供初步的动态语言支持(通过内置Mozilla JavaScriptRhino引擎实现)、提供编译期注解处理器和微型HTTP服务器API。Java虚拟 机内部:锁与同步、垃圾收集、类加载等。此外,八年历史的J2EE、J2SE、J2ME的产品线命名修改为Java EE 6、Java SE 6、JavaME 6。
2018年10月18日,Java SE 6 Update 211(JDK 6最后版本)发布(由于代码复杂性、Java开源、开发JavaFX、世界经济危机及Oracle对Sun的收购案等原因,JDK 6的升级补丁共计发布211次)。
2009年2月19日,JDK 7-Dolphin(海豚)发布第一个里程碑版本(规划十个里程碑。最后一个里程碑版本原计划定于2010年9月9日结束,但由于各种原因,JDK 7最终无法按计划完成)。
2011年7月28日,JDK 7-Dolphin(海豚)发布,改动特性:提供新的G1收集器(G1在发布时依然处于Experimental状态,直至2012年4月的Update 4中才正式商用)、加强对非Java语言的调用支持(JSR-292,这项特性在到JDK 11还有改动)、可并行的类加载架构、Fork/Join框架、switch语句块支持字符串等。从JDK 7 Update 4起,开始支持Mac OS X操作系统,并在JDK 7 Update 6中完全兼容Mac OS X;JDK 7 Update 6对ARM指令集架构提供了支持(此前仅支持x86、x86-64和SPARC指令集架构)。
2014年3月18日,JDK 8-Spider(蜘蛛)发布,语法特性:Lambda表达式、内置Nashorn JavaScript引擎的支持、新的时间日期API、彻底移除HotSpot的永久代、函数式接口、JavaFX等。
2017年9月21日,JDK 9发布,语法特性:Jigsaw、整顿HotSpot日志系统、JShell、默认垃圾回收期切换为G1、竞争锁性能优化。此后JDK将会在每年的3月和9月各发布一个大版本避免交付风险。此后每六个JDK大版本中才会被划出一个长期支持(Long Term Support,LTS)版,LTS版能够获得为期三年的支持和更新,普通版只有短短六个月的生命周期。JDK 8和JDK 11会是LTS版,再下一个就到2021年发布的JDK 17了。
2018年3月20日,JDK 10发布,内部重构:统一源仓库、统一垃圾收集器接口、统一即时编译器接口(JVMCI在JDK 9已经有了,这里是引入新的Graal即时编译器)等。
2018年3月,Oracle将Java EE所有权赠送给Eclipse基金会,不准再使用“Java”这个商标,此后改名为Jakarta EE。详见以下文章。Java EE重命名为Jakarta EE:Java EE Guardians与Oracle的分歧-InfoQ看新闻很累?看技术新闻更累?试试下载InfoQ手机客户端,每天上下班路上听新闻,有趣还有料!由于对Oracle不热心回应Java社区反馈感到失望,JavaEEGuardians于今年早些时候提交了一封公开信,表达了他们对Oracle限制使用EE4J的“Java”和“javax”包名的担忧。Oracle依据其商标使用准则,继续保持自己的立场。著名的JavaEE布道师RezaRahman,同时担任Cahttps://www.infoq.cn/article/2018/02/from-javaee-to-jakartaee
2018年9月25日,JDK 11发布(LTS版本),语法特性:ZGC垃圾收集器出现、Stream、String、Lambda语法等功能增强。
Oracle从JDK 11起把以前的商业特性全部开源给OpenJDK,这样OpenJDK 11和OracleJDK 11的代码和功能本质上是完全相同的。Oracle宣布以后将会同时发行两个JDK:一个是以GPLv2+CE协议下由Oracle发行的OpenJDK(本书后面章节称其为Oracle OpenJDK),另一个是在新的OTN协议下发行的传统的OracleJDK,这两个JDK共享绝大部分源码,在功能上是几乎一样的,核心差异是前者可以免费在开发、测试或生产环境中使用,但是只有半年时间的更新支持;后者个人依然可以免费使用,但若在生产环境中商用就必须付费,可以有三年时间的更新支持。
2019年2月,RedHat同时从Oracle手上接过OpenJDK 8和OpenJDK 11的管理权利和维护职责,RedHat代替Oracle成为JDK历史版本的维护者。
2019年3月20日,JDK 12发布,语法特性:Switch语句、Java微测试套件(JMH)、垃圾收集器算法Shenandoah等。RedHat领导开发的Shenandoah垃圾收集器与Oracle在JDK 11中发布的ZGC几乎完全一致,Oracle违背尽可能保证OracleJDK和OpenJDK的兼容一致,在OracleJDK 12里把Shenandoah的代码通过条件编译强行剔除掉,使其成为历史上唯一进入了OpenJDK发布清单,但在OracleJDK中无法使用的功能。
2019年9月17日,JDK 13发布,语法特性:ZGC垃圾收集器增强、Switch语句等。
2020年3月17日,JDK 14发布,语法特性: instanceof的模式匹配预览版本、Records预览版本、jpackage打包工具孵化、G1的NUMA内存分配优化、移除CMS垃圾收集器、弃用Parallel Scavenge和Serial Old垃圾收集算法的组合、ZGC移植到Windows和mac OS。
2020年9月15日,JDK 15发布,语法特性:instanceof的模式匹配预览版本、EdDSA 数字签名算法、隐藏类、Records预览版本、重新实现 Legacy DatagramSocket API、ZGC。
2021年3月16日,JDK 16发布,语法特性:instanceof发布、Records发布、jpackage打包工具发布等。
2021年9月14日,JDK 17发布(LTS版本),伪随机数生成器 (PRNG) 增强、删除实验性 AOT 和 JIT 编译器、switch功能增强等。
1.5.1 虚拟机始祖:Sun Classic/Exact VM(服务器、桌面领域)
1996年1月23日,Sun发布的JDK 1.0所带的虚拟机就是Classic VM。这款虚拟机只能使用纯解释器方式来执行Java代码,如果要使用即时编译器必须进行外挂,但是外挂即时编译器的话,即时编译器就会完全接管虚拟机的执行系统,解释器便不能再工作了。在JDK 1.2及之前,用户用Classic虚拟机执行java-version命令,将会看到类似下面这行的输出:
java version "1.2.2"
Classic VM(build JDK-1.2.2-001,green threads,sunwjit)
“sunwjit”(Sun Workshop JIT)就是Sun提供的外挂编译器,其他类似的外挂编译器还有Symantec JIT和shuJIT等。由于解释器和编译器不能配合工作,意味着使用编译执行时不得不对每一个方法、每一行代码都进行编译。
Sun的虚拟机团队在JDK 1.2时,曾在Solaris平台上发布过一款名为Exact VM的虚拟机,它的编译执行系统已经具备热点探测、两级即时编译器、编译器与解释器混合工作模式等。Exact VM因它使用准确式内存管理(Exact Memory Management,也可以叫Non-Conservative/Accurate Memory Management)而得名。
准确式内存管理是指虚拟机可以知道内存中某个位置的数据具体是什么类型。譬如内存中有一个32bit的整数123456,虚拟机将有能力分辨出它到底是一个指向了123456的内存地址的引用类型还是一个数值为123456的整数,准确分辨出哪些内存是引用类型,这也是在垃圾收集时准确判断堆上的数据是否还可能被使用的前提。由于使用了准确式内存管理,Exact VM可以抛弃掉以前Classic VM基于句柄(Handle)的对象查找方式(原因是垃圾收集后对象将可能会被移动位置,如果地址为123456的对象移动到654321,在没有明确信息表明内存中哪些数据是引用类型的前提下,那虚拟机肯定是不敢把内存中所有为123456的值改成654321的,所以要使用句柄来保持引用值的稳定),这样每次定位对象都少了一次间接查找的开销,显著提升执行性能。
虽然Exact VM的技术相对Classic VM来说先进了许多,但是它只存在了很短暂的时间就被外部引进的HotSpot VM所取代。而Classic VM的生命周期则相对要长不少,它在JDK 1.2之前是JDK中唯一的虚拟机,在JDK 1.2时,它与HotSpot VM并存,但默认是使用Classic VM(用户可用java-hotspot参数切换至HotSpot VM),而在JDK 1.3时,HotSpot VM成为默认虚拟机,它仍作为虚拟机的“备用选择”发布(使用java-classic参数切换),直到JDK 1.4的时候,Classic VM才完全退出商用虚拟机的历史舞台,与Exact VM一起进入了Sun Labs Research VM之中。
1.5.2 武林盟主:HotSpot VM(服务器、桌面领域)
HotSpot虚拟机是Sun/OracleJDK和OpenJDK中的默认Java虚拟机,也是目前使用范围最广的Java虚拟机。HotSpot虚拟机来源于Strongtalk虚拟机,由“Longview Technologies”公司设计,这款虚拟机中相当多的技术来源于一款为支持Self语言实现“达到C语言50%以上的执行效率”的目标而设计的Self虚拟机,Sun公司在1997年收购了Longview Technologies公司,从而获得了HotSpot虚拟机。
其实HotSpot与Exact虚拟机基本上是同时期的独立产品,HotSpot出现得还稍早一些,一开始HotSpot就是基于准确式内存管理的,而Exact VM之中也有与HotSpot几乎一样的热点探测技术,为了Exact VM和HotSpot VM哪个该成为Sun主要支持的虚拟机,在Sun公司内部还争吵过一场,HotSpot击败Exact并不能算技术上的胜利。
HotSpot虚拟机的热点代码探测能力可以通过执行计数器找出最具有编译价值的代码,然后通知即时编译器以方法为单位进行编译。如果一个方法被频繁调用,或方法中有效循环次数很多,将会分别触发标准即时编译和栈上替换编译(On-Stack Replacement,OSR)行为。通过编译器与解释器恰当地协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无须等待本地代码输出才能执行程序,即时编译的时间压力也相对减小,这样有助于引入更复杂的代码优化技术,输出质量更高的本地代码。
2006年,Sun陆续将SunJDK的各个部分在GPLv2协议下开放了源码,HotSpot从此成为Sun/OracleJDK和OpenJDK两个实现极度接近的JDK项目的共同虚拟机。Oracle收购Sun以后把BEA JRockit(Oracle已收购BEA公司的JRockit)中的优秀特性融合到HotSpot之中。HotSpot在这个过程里移除掉永久代,吸收了JRockit的Java Mission Control监控工具等功能。
1.5.3 小家碧玉:Mobile/Embedded VM(JAVA ME领域)
上面介绍到的是两款服务器、桌面领域的商用虚拟机。面对移动和嵌入式市场,Oracle在Java ME也有面向高端的CDC-HI(Connected Device Configuration-HotSpot Implementation)和面向低端的CLDC-HI(Connected Limited Device Configuration -HotSpot Implementation)两款虚拟机,这两款虚拟机只是借鉴过HotSpot的一些技术,并没有任何直接关系。
智能手机已被Android和iOS二分天下,所以CDC-HI和CLDC-HI现在处于比较尴尬的位置,仍不处于乐观的局面。
在嵌入式设备上,CDC-HI经过多年的扩充,在核心部分其实已经跟Java SE非常接近,能用Java SE的地方大家更愿意用Java ME,Oracle也基本上砍掉了CDC-HI的所有项目,把它们都划归到了Java SE Embedded下。Java SE Embedded里带的Java虚拟机是为了适应嵌入式环境专门定制裁剪的HotSpot,尽可能在支持完整的Java SE功能的前提下向着减少内存消耗的方向优化,譬如只留下了客户端编译器(C1),去掉了服务端编译器(C2);只保留 Serial/Serial Old垃圾收集器,去掉了其他收集器等。
面向更低端设备的CLDC-HI倒是在智能控制器、传感器等领域还算能维持自己的一片市场,现在也还在继续发展,但前途并不乐观。目前CLDC中活得最好的产品反而是原本早该被CLDC-HI淘汰的KVM,国内的老人手机和出口到经济欠发达国家的功能手机(Feature Phone)还在广泛使用这种更加简单、资源消耗也更小的上一代Java ME虚拟机。
1.5.4 天下第二:BEA JRockit/IBM J9 VM(服务器、桌面领域)
BEA System公司的JRockit与IBM公司的IBM J9曾经与HotSpot并称“三 大商业Java虚拟机”。 JRockit是BEA在2002年从Appeal Virtual Machines公司收购获得的Java虚拟机。BEA将其发展为一款专门为服务器硬件和服务端应用场景高度优化的虚拟机,由于专注于服务端应用,它可以不太关注于程序启动速度,因此JRockit内部不包含解释器实现,全部代码都靠即时编译器编译后执行。除此之外,JRockit的垃圾收集器和Java Mission Control故障处理套件等部分的实现,在当时众多的Java虚拟机中也处于领先水平。由于BEA System公司被Oracle收购,所以现已不再继续发展。
IBM J9是IBM主力发展的虚拟机(IBM公司拥有多款Java虚拟机),正式名称是“IBM Technology for Java Virtual Machine”(简称IT4),由于这个名字太拗口,因此大家习惯用内部开发代号J9。IBM J9是一款在设计上全面考虑服务端、桌面应用,再到嵌入式的多用途虚拟机,开发J9的目的是作为IBM公司各种Java产品的执行平台,在和IBM产品搭配以及在IBM AIX和z/OS这些平台上部署Java应用。
J9由IBM的SmallTalk虚拟机项目扩展而来,这个虚拟机有一个Bug是因为8KB常量值定义错误引起,工程师们花了很长时间终于发现并解决了这个错误,此后这个版本的虚拟机就被称为K8,后来由其扩展而来、支持Java语言的虚拟机就被命名为J9。
除BEA和IBM公司外,其他一些大公司也号称有自己的专属JDK和虚拟机,但是它们要么是通过从Sun/Oracle公司购买版权的方式获得的(如HP、SAP等),要么是基于OpenJDK项目改进而来的(如阿里巴巴、Twitter等),都并非自己独立开发。
1.5.5 软硬合璧:BEA Liquid VM/Azul VM(硬件领域)
高性能Java虚拟机一般是指HotSpot、JRockit、J9这类在通用硬件平台上运行的商用虚拟机,但其实还有一类与特定硬件平台绑定、软硬件配合工作的专有虚拟机,往往能够实现更高的执行性能,这类专有虚拟机的代表是BEA Liquid VM和Azul VM。
Liquid VM也被称为JRockit VE(JRockit Virtual Edition),它是BEA公司开发的可以直接运行在自家Hypervisor系统上的JRockit虚拟机的虚拟化版本,Liquid VM不需要操作系统的支持,因为它自己本身实现了一个专用操作系统的必要功能,如线程调度、文件系统、网络支持等。由虚拟机越过通用操作系统直接控制硬件可以最大限度地发挥硬件的能力,如在线程调度时,不需要再进行内核态/用户态的切换,提升Java程序的执行性能。随着JRockit虚拟机终止开发,Liquid VM项目也停止了。
Azul VM是Azul Systems公司在HotSpot基础上进行大量改进,运行于Azul Systems公司的专有硬件Vega系统上的Java虚拟机,每个Azul VM实例都可以管理至少数十个CPU和数百GB的内存的硬件资源,并提供在巨大内存范围内停顿时间可控的垃圾收集器(即业内赫赫有名的PGC和C4收集器),为专有硬件优化的线程调度等优秀特性。令人惋惜的是,Java虚拟机变得越来越强大的同时也越来越复杂,要推动在专有硬件上的Java虚拟机升级发展,难以直接借助开源社区的力量,往往需要耗费更高昂的成本,这一缺陷使得专有虚拟机逐渐没落,Azul Systems公司最终放弃了Vega产品线,把全部精力投入到Zing产品线(Zing虚拟机可以在通用x86平台上提供接近于Vega系统的性能和一致的功能特性)。
Zing虚拟机是一个从HotSpot某旧版代码分支基础上独立出来重新开发的高性能Java虚拟机,它可以运行在通用的Linux/x86-64平台上。Azul公司为它编写了新的垃圾收集器,也修改了HotSpot内的许多实现细节,在要求低延迟、快速预热等场景中,Zing VM都要比HotSpot表现得更好。Zing的PGC、C4收集器可以轻易支持TB级别的Java堆内存,而且保证暂停时间仍然可以维持在不超过10毫秒的范围里,HotSpot要一直到JDK 11和JDK 12的ZGC及Shenandoah收集器才达到了相同的目标,而且目前效果仍然远不如C4。Zing的ReadyNow!功能可以利用之前运行时收集到的性能监控数据,引导虚拟机在启动后快速达到稳定的高性能水平,减少启动后从解释执行到即时编译的等待时间。Zing自带的ZVision/ZVRobot功能可以方便用户监控Java虚拟机的运行状态,从找出代码热点到对象分配监控、锁竞争监控等。Zing能让普通用户无须了解垃圾收集等底层调优,就可以使得Java应用享有低延迟、快速预热、易于监控的功能,这是Zing的核心价值和卖点,很多Java应用都可以通过长期努力在应用、框架层面优化来提升性能,但使用Zing的话就可以把精力更多集中在业务方面。
1.5.6 挑战者:Apache Harmony/Google Android Dalvik VM(未通过TCK认证领域)
Apache Harmony是一个Apache软件基金会旗下以Apache License协议开源的实际兼容于JDK 5和JDK 6的Java程序运行平台,它含有自己的虚拟机和Java类库API,用户可以在上面运行Eclipse、Tomcat、Maven等常用的Java程序。由于它并没有通过TCK认证,所以我们不能用一句“Apache的JDK”或者“Apache的Java虚拟机”来直接代指。Sun公司把自家的JDK开源形成OpenJDK项目之后,Apache Harmony开源的优势被极大地抵消。虽然Harmony没有真正地被大规模商业运用过,但是它的许多代码(主要是Java类库部分的代码)被吸纳进IBM的JDK 7实现以及Google Android SDK之中,尤其是对Android的发展起了很大推动作用。
如果一个公司要宣称自己的运行平台“兼容于Java技术体系”,那该运行平台就必须要通过TCK(Technology Compatibility Kit)的兼容性测试,Apache基金会曾要求当时的Sun公司提供TCK的使用授权,但是一直遭到各种理由的拖延和搪塞,直到Oracle收购了Sun公司之后,双方关系越闹越僵,最终导致Apache基金会愤然退出JCP组织,这是Java社区有史以来最严重的分裂事件之一。
Dalvik虚拟机曾经是Android平台的核心组成部分之一,并不是一个Java虚拟机,它没有遵循《Java虚拟机规范》,不能直接执行Java的Class文件,使用寄存器架构而不是Java虚拟机中常见的栈架构。但是它与Java却又有着千丝万缕的联系,它执行的DEX(Dalvik Executable)文件可以通过Class文件转化而来,使用Java语法编写应用程序,可以直接使用绝大部分的Java API等。在Android发展的早期,Dalvik虚拟机随着Android的成功迅速流行,在Android 2.2中开始提供即时编译器实现,执行性能又有了进一步提高。不过到了Android4.4时代,支持提前编译(Ahead of Time Compilation,AOT)的ART虚拟机迅速崛起,在当时性能还不算特别强大的移动设备上,提前编译要比即时编译更容易获得高性能,所以在Android 5.0里ART就全面代替了Dalvik虚拟机。
1.5.7 没有成功,但并非失败:Microsoft JVM及其他(其他)
Microsoft JVM是微软为了在Internet Explorer 3浏览器中支持Java Applets应用开发的在Windows平台的版本运行的虚拟机(Java语言初期主要应用之一是在浏览器中运行Java Applets程序 ),是当时Windows系统下性能最好的Java虚拟机。1997年10月,Sun公司正式以侵犯商标、不正当竞争等罪名控告微软,这款虚拟机也曾作为微软公司垄断调查的证据之一被呈送法庭。微软向Sun公司赔偿2000万美金,承诺终止其Java虚拟机的发展,并逐步在产品中移除Java虚拟机相关功能。
1.5.8 百家争鸣(小众领域)
还有一些Java虚拟机不是单纯为了用于生产,仅仅是用于研究、验证某种技术和观点,又或者是作为一些规范的标准实现。以下列举几款较为有影响的:
名称 | 简介 |
KVM | KVM(Kilobyte Virtual Machine)强调简单、轻量、高度可移植,但是运行速度比较慢。在Android、iOS等智能手机操作系统出现前曾经在手机平台上得到非常广泛应用。 |
Java Card VM | JCVM是Java虚拟机很小的一个子集,裁减了许多模块但通常支持绝大多数的常用加密算法。JCVM必须精简到能放入智能卡、SIM卡、银行信用卡、借记卡内,负责对Java Applet程序进行解释执行。 |
Squawk VM | Squawk VM是由Sun开发,运行于Sun SPOT(一种手持的Wi-Fi设备),也曾经运用于Java Card。这是一个Java代码比重很高的嵌入式虚拟机实现,其中诸如类加载器、字节码验证器、垃圾收集器、解释器、编译器和线程调度都是用Java语言完成的,仅仅靠C语言来编写设备I/O和必要的本地代码。 |
JavaInJava | JavaInJava是Sun公司在1997年~1998年间所研发的一个实验室性质的虚拟机,从名字就可以看出,它试图以Java语言来实现Java语言本身的运行环境,既所谓的“元循环”(Meta-Circular,是指使用 语言自身来实现其运行环境)虚拟机。它必须运行在另外一个宿主虚拟机之上,内部没有即时编译 器,代码只能以解释模式执行。在上世纪末主流原生的Java虚拟机都未能很好解决性能问题的时代, 开发这种项目,其执行速度大家可想而知,不过通过元循环证明一门语言可以自举,是具有它的研究价值的。 |
Maxine VM | Maxine VM和上面的JavaInJava非常相似,它也是一个几乎全部以Java代码实现(只有用于启动 Java虚拟机的加载器使用C语言编写)的元循环Java虚拟机。这个项目于2005年开始,到现在仍然在发 展之中,比起JavaInJava,Maxine VM的执行效率就显得靠谱得多,它有先进的即时编译器和垃圾收集 器,可在宿主模式或独立模式下执行,其执行效率已经接近HotSpot虚拟机Client模式的水平。后来有 了从C1X编译器演进而来的Graal编译器的支持,就更加如虎添翼,执行效率有了进一步飞跃。Graal编 译器现在已经是HotSpot的默认组件,是未来代替HotSpot中服务端编译器的希望。 |
Jikes RVM | Jikes RVM是IBM开发的专门用来研究Java虚拟机实现技术的项目。曾用名为Jalapeño。与 JavaInJava和Maxine一样,它也是一个元循环虚拟机。 |
IKVM.NET | 这是一个基于微软.NET框架实现的Java虚拟机,并借助Mono获得一定的跨平台能力。IKVM.NET 的目标第一眼看起来的确很奇怪,可能在某些特殊情况下,在.NET上使用某些流行的Java库也许真的 不算是伪需求?IKVM.NET可以将Class文件编译成.NET Assembly,在任意的CLI上运行。 |
JamVM | JamVM -- A compact Java Virtual Machine |
CacaoVM | Cacao VM |
SableVM | SableVM Project |
Kaffe | The Kaffe Virtual Machine |
Jelatine JVM | Jelatine JVM -- A Java virtual machine for small embedded systems |
NanoVM | http://www.harbaum.org/till/nanovm/index.shtml |
MRP | https://github.com/codehaus/mrp |
Moxie JVM | http://moxie.sourceforge.net/ |