第1章 走近Java

1.1 概述

了解 Java 技术

1.2 Java技术体系

广义上:
Kotlin、Clojure、JRuby、Groovy等运行在Java虚拟机上的编程语言及其相关的程序都属于Java技术体系中的一员。

JCP官方定义的Java技术体系:

  • Java程序设计语言
  • 各种硬件平台上的Java虚拟机实现
  • Class文件格式
  • Java类库API
  • 来自商业机构和开源社区的第三方Java类库

1.3 Java发展史

1991年James Gosling 启动 Oak
1995年Oak改名Java,口号:“Write Once ,Run Anywhere”
1996年JDK 1.0发布。首届JavaOne大会
1997年JDK 1.1发布
1998年JDK1.2发布,Java技术体系拆分三个方向J2SE , J2EE , J2ME
1999年HotSpot虚拟机诞生,JDK1.2之后的默认Java虚拟机
2000年JDK 1.3发布。Sun公司开始每隔两年发布一个JDK主版本
2002年JDK 1.4发布,Java真正走向成熟。微软推出.net
2004年JDK 5发布,语法改动很大。放弃"JDK 1.x"的命名方式
2006年JDK 6发布。Sun公司宣布Java开源,建立OpenJDK组织对源码独立管理
2009年JDK 7发布,Oracle收购Sun
2014年JDK 8发布
2017年JDK 9发布。
-为了避免众多功能特性被集中捆绑到一个JDK版本上而引发交付风险,Oracle宣布JDK将会在每年的3月和9月各发布一个大版本。从此以后,每六个JDK大版本中才会被画出一个长期支持版(LTS),只有LTS版的JDK能获得为其三年的支持和更新,普通版本的JDK只有六个月生命周期。
2018年JDK 10发布、JDK11发布
-Oracle砍掉Java EE,将其所有权赠送给Eclipse基金会,改名为Jakarta EE。
-Oracle宣布停办JavaOne大会。
-从JDK 11之后,将会同时发行两个JDK:OpenJDK 和 OracleJDK 。这两个JDK共享绝大部分源码,功能上几乎一样,差别在于:OpenJDK可以免费在开发、测试或生产环境中使用,但是只有半年时间的更新支持;OracleJDK 个人依然可以免费使用,但若在生产环境中商用就必须付费,可以有三年时间的更新支持。
2019年JDK 12发布

1.4 Java虚拟机家族

1.4.1 虚拟机始祖:Sun Classic/Exact VM

Classic VM

世界上第一款商用Java虚拟机

1996年1月23日,JDK 1.0 发布,这个JDK中所带的虚拟机就是Classic VM。

这款虚拟机只能使用纯解释器方式来执行Java代码,如果要使用即时编译器那就必须进行外挂,但是假如外挂了即时编译器,即时编译器就会完全接管虚拟机的执行系统,解释器便不能再工作了。

由于解释器和编译器不能配合工作,这就意味着如果要使用编译执行,编译器就不得不对每一个方法、每一行代码都进行编译,而无论它们执行的频率是否具有编译的价值。

Exact VM

Sun公司的虚拟机团队努力去解决Classic VM所面临的各种问题,提升运行效率,在JDK1.2时,曾在Solaris平台发布过一款名为Exact VM 的虚拟机,它的编译执行系统已经具备现代高性能虚拟机雏形,如热点探测、两级即时编译器、编译器与解释器混合工作的模式等。

Exact VM 因它使用 准确式内存管理(Exact Memory Management)而得名。准确式内存管理是指虚拟机可以知道内存中某个位置的数据具体是什么类型。譬如内存中有一个32bit的整数123456,虚拟机将有能力分辨出它到底时一个指向123456的内存地址的引用类型还是一个数值为123456的整数,准确分辨出哪些内存是引用类型,这也是在垃圾收集时准确判断堆上的数据是否还可能被使用的前提。由于使用了准确式内存管理,Exact VM 可以抛弃掉以前Classic VM基于句柄的对象查找方式(原因是垃圾收集后对象将可能会被移动位置,如果地址为123456的对象移动到654321,在没有明确信息表明内存中那些数据是引用类型的前提下,那虚拟机肯定是不敢把内存中所有为123456的值改成654321的,所以要使用句柄来保持引用值的稳定),这样每次定位对象都少了一次间接查找的开销,显著提升执行性能。

虽然Exact VM 的技术相对Classic VM来说先进了许多,但是它的命运显得十分英雄气短,在商业应用上只存在了很短暂的时间就被外部引进的HotSpot VM所取代,甚至还没来得及发布Windows和Linux平台下的商用版本。而Classic VM的生命周期则相对要长不少,它在 JDK 1.2 之前是 JDK 唯一的虚拟机,在 JDK 1.2 时,它与HotSpot VM 并存,并默认使用Classic VM,而在 JDK 1.3 时,HotSpot VM 成为默认虚拟机,它仍作为虚拟机的备用选择发布,直到 JDK 1.4的时候,Classic VM 才完全退出商用虚拟机的历史舞台,与Exact VM 一起进入了Sun Labs Research VM之中。

1.4.2 武林盟主:HotSpot VM

它是 Sun/OracleJDK 和 OpenJDK 中默认的Java虚拟机,也是目前使用范围最广的Java虚拟机。
HotSpot 既继承了Sun之前两款商用虚拟机的优点,也有许多自己新的技术又是,如它名称中的HotSpot指的就是它的热点代码探测技术,HotSpot VM 的热点代码探测能力可以通过执行计数器找出最具有编译价值的代码,然后通过即时编译器以方法为单位进行编译。如果一个方法被频繁调用,或方法中有效循环次数很多,将会分别触发标准即时编译和栈上替换编译(On-Stack Replacement ,OSR)行为。通过编译器与解释器恰当地协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无需等待本地代码输出才能执行程序,即时编译的时间压力也相对减小,这样有助于引入更复杂的代码优化技术,输出质量更高的本地代码。

2006年,Sun 陆续将SunJDK的各个部分开放了源码,形成了OpenJDK项目,其中当然也包括HotSpot 虚拟机。
Oracle收购Sun以后,建立了HotRockit项目,把原来BEA JRockit 中的优秀特性融合到HotSpot之中。到2014年的JDK 8 时期,里面的HotSpot就已经是两者融合的结果,HotSpot在这个过程里移除掉永久代,吸收了JRockit 的Java Mission Control 监控工具等功能。

1.4.3 小家碧玉:Mobile/Embedded VM

面向移动和嵌入式市场的Java虚拟机

1.4.4 天下第二:BEA JRockit/IBM J9 VM

曾经并称“三大商业Java虚拟机”:HotSpot 、JRockit、IBM J9

JRockit虚拟机曾经号称是“世界上速度最快的Java虚拟机”,专门为服务器硬件和服务端应用场景高度优化的虚拟机,由于专注于服务端应用,它可以不太专注于程序启动速度,因此JRockit内部不包含解释器实现,全部代码都靠即时编译器编译后执行。随着BEA被Oracle收购,JRockit现已不在继续发展。

IBM J9 虚拟机与JRockit只专注与服务端应用各不同,IBM J9虚拟机的市场定位与HotSpot比较接近,是一款在设计上全面考虑服务端、桌面应用,再到嵌入式的多用途虚拟机,开发J9的目的是作为IBM公司各种Java产品的执行平台,在和IBM产品搭配以及在IBM AIX和z/OS这些平台上部署Java应用。
J9知道今天仍然十分活跃,它的职责分离与模块化做的比HotSpot更优秀。从2016年起,IBM逐步将J9虚拟机进行开源,完全开源后便将它捐献给Eclipse基金会管理,并重新命名为OpenJ9 。

1.4.5 软硬合璧:BEA Liquid VM/Azul VM

Liquid VM也被称为JRockit VE,它是BEA公司开发的可以直接运行在自家Hypervisor系统上的JRockit虚拟机的虚拟化版本,Liquid VM不需要操作系统支持。由虚拟机越过通用操作系统直接控制硬件可以获得很多好处,这样可以最大限度地发挥硬件的能力,提升Java程序的执行性能。随着JRockit虚拟机种植开发,Liquid VM项目也已经停止了。

Azul VM 是Azul Systems公司在HotSpot基础上进行大量改进,运行于Azul Systems公司的专有硬件Vega系统上的Java虚拟机,每个Azul VM实例都可以管理至少数十个CPU和数百GB内存的硬件资源,并提供在巨大内存范围内停顿时间可控的垃圾收集器(即业内赫赫有名的PGC和C4收集器),为专有硬件优化的线程调度等优秀特性。2010年起,Azul公司的中心逐渐开始从硬件转向软件,发布了自己的Zing虚拟机,可以在通用x86平台提供接近于Vega系统的性能和一致的功能特性。
随着虚拟机技术的不断发展,Java虚拟机变得越来越强大的同时也越来越复杂,要推动在专有硬件上的Java虚拟机升级发展,难以直接借助开源社区的力量,往往需要耗费更高昂的成本,在商业上的缺陷使得专有虚拟机逐渐没落,Azul Systems公司最终也放弃了Vega产品线,把全部精力投入到Zing和Zulu产品线中。
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.4.6 挑战者:Apache Harmony/Google Android Dalvik VM

Harmony虚拟机和Dalvik虚拟机只能称作“虚拟机”,而不能称作“Java虚拟机”,但是这两款虚拟机以及背后所代表的技术体系曾经对Java生态产生了非常大的影响和挑战,当时甚至有悲观的人认为成熟的Java生态系统都有分裂和崩溃的可能。

Apache Harmony是一个Apache软件基金会旗下以Apache License协议开源的实际兼容于JDK 5和JDK 6的Java程序运行平台,它含有自己的虚拟机和Java类库API,用户可以在上面运行Eclipse、Tomcat、Maven等常用的Java程序。但是,它并没有通过TCK认证,所以我们不得不用一长串冗长拗口的语言来介绍它,而不能用一句“Apache 的JDK”或者“Apache的Java虚拟机”来直接代指。
如果一个公司要宣称自己的运行平台“兼容于Java技术体系”,那该运行平台就必须要通过TCK(Technology Compatibility Kit)的兼容性测试,Apache基金会曾要求当时的Sun公司提供TCK的使用授权,但是一直遭到各种理由的拖延和搪塞,直到Oracle收购了Sun公司之后,双方关系越闹越僵,最终导致Apache基金会愤然退出JCP组织,这是Java社区有史以来最严重的分裂事件之一。
当Sun公司把自家的JDK开源形成OpenJDK项目之后,Apache Harmony开源的优势被极大地抵消,以至于连Harmony项目的最大参与者IBM公司也宣布辞去Harmony项目管理主席的职位,转而参与OpenJDK的开发。虽然Harmony没有真正地被大规模商业运用过,但是它的许多代码(主要是Java类库部分的代码)被吸纳进IBM的JDK 7实现以及Google Android SDK之中,尤其是对Android的发展起了很大推动作用。

Dalvik虚拟机曾经是Android 平台的核心组成部分之一,它的名字来源于冰岛的一个名为Dalvik的小渔村。Dalvik虚拟机并不是一个Java虚拟机,它没有遵循《Java虚拟机规范》,不能直接执行Java的Class文件,使用寄存器架构而不是Java虚拟机中常见的栈架构。但是它与Java却又有着千丝万缕的联系,它执行的DEX文件可以通过Class文件转化而来,使用Java语法编写应用程序,可以直接使用绝大部份的Java API等。从Android 4.4开始,支持提前编译的ART虚拟机迅速崛起。在Android 5.0里ART就全面代替了Dalvik虚拟机。

1.4.7 没有成功,但并非失败:Microsoft JVM 及其他

1.4.8 百家争鸣

1.5 展望Java技术的未来

1.5.1 无语言倾向

2018年4月,Oracle Labs新公开了一项黑科技:Graal VM。Graal VM官方称为“Universal VM”和“Polyglot VM”,这是一个在HotSpot虚拟机基础上增强而成的跨语言全栈虚拟机,可以作为“任何语言”的运行平台使用。

1.5.2 新一代即时编译器

Graal 编译器
以C2编译器替代者的身份登场

1.5.3 向Native迈进

对不需要长时间运行的,或者小型化的应用而言,Java天生就带有一些劣势。
跑个HelloWorld都需要几百兆的JRE
近几年在从大型单体应用架构向小型微服务应用架构发展的技术潮流下,Java表现出不适应。
Java的启动时间相对较长,需要预热才能达到最高性能。
无服务的架构中,Java更显不足。

Java陆续推出跨进程的、可以面向用户程序的类型信息共享(Application Class Data Sharing , AppCDS , 允许把加载解析后的类型信息缓存起来,从而提升下次启动速度)、无操作的垃圾收集器(Epsilon,制作内存分配而不做回收的收集器,对于运行完就退出的应用十分合适)等改善措施。而酝酿中的一个更彻底的解决方案,是逐步开始对提前编译(Ahead of Time Compilation, AOT)提供支持。

提前编译是相对于即时编译的概念,好处是Java虚拟机加载这些已经预编译成二进制库之后就能直接调用,而无须再等待即时编译器在运行时将其编译成二进制机器码。理论上,提前编译可以减少即时编译带来的预热时间,减少Java应用长期给人带来的“第一次运行慢”的不良体验

Substrate VM的出现,满足了人们心中对Java提前编译的全部期待。Substrate VM是在Graal VM 0.20版本里新出现的一个极小型的运行时环境

1.5.4 灵活的胖子

二十年间有无数改进和功能不断的添加到HotSpot的源码上,只是它成长为今天这样的庞然大物。
经过一系列的重构与开放,HotSpot虚拟机逐渐从时间的侵蚀中挣脱出来,虽然代码复杂度还在增长,体积仍然在变大,但是其架构并未老朽,二十拥有了越来越多的开放性和扩展性,使得HotSpot称为一个能够联动外部功能,能够应对各种场景,能够学会十八般武艺的身手灵活敏捷的“胖子”。

1.5.5 语言语法持续增强

语法糖
Project Loom 提供更加轻量级的、由软件自身进行调度的用户线程。
Project Valhalla 提供值类型和基本类型的泛型支持,并提供明确的不可变类型和非引用类型的申明。
Project Panama 提供更好的方式让Java代码与本地代码进行调用和传输数据。

1.6 实战:自己编译JDK

1.6.1 获取源码

https://hg.openjdk.java.net/jdk/jdk12/

1.6.2 系统需求

Linux GCC 4.8以上或CLang 3.2以上
MacOS X 10.13版本以上 ,XCode,Command Line Tools for XCode
Windows

1.6.3 构建编译环境

Linux
MacOS

1.6.4 进行编译

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值