读书笔记:《深入理解Java虚拟机》——(序)

其实老早就在多看上买了这本书的电子版,总感觉看电子书没有感觉(算是给自己懒找个借口吧),后来赶上当当活动,入手了纸质版,现在终于一口气看完了。合上书回想一下,感觉收获不少,但也有种不踏实的感觉,不写点什么巩固一下记忆总怕自己转眼就忘干净了,所以就有了这个分类,督促自己要养成这个好习惯,边读边记笔记,而不是后补。

认识Java

首先,要重新认识一下Java。“Java不仅仅是一门编程语言,还是一个由一系列计算机软件和规范形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境”。

从广义上讲运行在Java虚拟机上的语言以及相关程序都属于Java技术体系中的一员,如Groovy、Scala和Kotlin等。Sun官方所定义的Java技术体系包括:Java程序设计语言、各种硬件平台上的Java虚拟机、Class文件格式、Java API类库、第三方Java类库。其中,Java语言+Java虚拟机+Java API就是通常所说的JDK(Java Development Kit)了。下图表示Java技术体系所包含的内容(图片来源网络,侵删)。
Java技术体系所包含的内容

Java发展史

时间 事件
1991年4月 James Gosling博士领导的绿色计划(Green Project)启动,这个计划的产品就是Java语言的前身:Oak(橡树)。
1995年5月23日 Oak语言改名为Java,在SunWorld大会上正式发布Java 1.0版本,第一次提出“Write Once,Run Any-where”的口号。
1996年1月23日 JDK 1.0发布,包含Sub Classic VM。
1997年2月19日 JDK 1.1发布,包含Jar文件格式、JDBC、JavaBean、RMI,出现内部类、反射。
~1999年4月8日 一共发布了1.1.0~1.1.8九个版本
1998年12月4日 JDK 1.2发布,分为J2SE(桌面)、J2EE(企业级)、J2ME(移动终端)三个方向,虚拟机第一次内置了JIT(Just In Time)编译器。
1999年3月 JDK 1.2.1发布
1999年7月 JDK 1.2.2发布
1999年4月27日 HotSpot虚拟机发布。
2000年5月8日 JDK 1.3发布,改进了数学运算、新的Timer API等。
2001年5月17日 JDK 1.3.1发布。
2002年2月13日 JDK 1.4发布,是Java真正走向成熟的一个版本,新特性包括:正则表达式、异常链、NIO、日志类、XML解析器和XSLT转换器等。
2004年9月30日 JDK 1.5发布[1],在语法易用性上做了很大改进:自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环(foreach),改进了内存模型,提供了java.util.concurrent并发包。
2006年12月11日 JDK 1.6发布,命名方式改为Java SE 6、Java EE 6、Java ME 6,提供了动态语言支持(通过内置Mozilla JavaScript Rhino引擎实现)、提供编译API和微型HTTP服务器API等。
2006年11月13日 Sun公司在JavaOne大会上宣布会将Java开源,并在随后的一年多将JDK在GPL v2协议下开源,建立了OpenJDK组织进行管理。
2009年2月19日 JDK 1.7完成了第一个里程碑版本,主要改进包括:G1收集器(Update 4中才转正)、升级类加载架构等。
2014年3月18日 JDK 1.8发布,支持Lambda表达式,提供函数式接口,新的JavaScript引擎(Nashorn),新的Stream API,新的时间日期API,接口支持默认方法和静态方法等。
2017年9月21日 JDK 9发布,支持模块化,提供了交互式编程环境jshell。JDK 9是一个短期版本,之后将改为每半年发布一个大版本。
2018年3月21日 JDK 10发布,带来了12个JEP(JDK Enhancement Proposal 特性加强提议),如:var局部变量类型推断、统一的垃圾回收接口。JDK 10也是一个短期版本。
2018年9月25日 Java 11 (18.9 LTS)发布,这是继JDK 8以来第一个长期支持版本。JavaFX从JDK中分离为独立模块,以及17个JEP。
2019年3月19日 JDK 12将发布正式版[2]

Java虚拟机发展史

Sun Classic/Exact VM

Sun Classic VM是世界上第一款商用Java虚拟机,伴随JDK 1.0发布。只能用纯解释执行的方式运行Java代码,可以通过外挂JIT编译器,但如果外挂了JIT编译器,虚拟机解释器将不再工作,执行系统会被JIT编译器完全接管。

在JDK 1.2时,在Solaris平台发布了一款名为Exact VM的虚拟机,他包含两级即时编译器、编译器与解释器混合工作模式等。因使用准确式内存管理(Exact Memory Management,也可以叫Non-Conservative/Accurate Memory Management,即虚拟机可以知道内存中某个位置的数据具体是什么类型)而得名。

Sun HotSpot VM

Sun JDK和Open JDK带的虚拟机,目前使用范围最广的虚拟机。

Sun 公司其他虚拟机

Sun公司还发布过一些嵌入式虚拟机以及一些仅用于研究的虚拟机。

BEA JRockit/IBM J9 VM

JRockit是一款服务器硬件和服务器端应用场景高度优化的虚拟机,不包含解释器,全部代码靠即时编译器编译后运行,JRockit的垃圾收集器和MissionControl服务套件等部分的实现,在众多Java虚拟机中也一直处于领先水平。

IBM J9 VM是IBM主力发展的一款Java虚拟机,和Sun HotSpot类似,是一款可以用于服务器端、桌面应用以及嵌入式环境的多用途虚拟机。

Azul VM/BEA Liquid VM

与经常见到的HotSpot、JRockit等通用平台上的虚拟机不同,Azul VM/BEA Liquid VM这类虚拟机在特定的硬件平台进行了大量有针对性的改进,可以在这些平台上拥有更高的性能。

Apache Harmony/Google Android Dalvik VM

Apache Harmony兼容JDK1.5和JDK1.6,用户可以在Apache Harmony上运行Eclipse、Tomcat、Maven等常见的Java程序,但严格来说Apache Harmony不能称之为"Java虚拟机",这是因为Apache Harmony没有获取到TCK(Technology CompatibilityKit)。

Google的Android让Java真正走进了移动设备领域,Dalvik VM是Android平台的核心组成部分之一,但Dalvik VM也不是一个Java虚拟机,因为它并没有遵循虚拟机规范,不能直接运行Class文件,使用寄存器架构;但它又和Java有着千丝万缕的关系,它执行的dex(Dalvik Executable)文件可以通过Class文件转换而来,使用Java语言进行开发,也可以使用大部分Java API。

Microsoft VM及其他

微软曾经是Java的铁杆粉丝,然而争夺Java的控制权,令Java从跨平台变为绑定到Windows上的技术才是微软的主要目的。在Java语言诞生初期,Java的主要应用之一就是在浏览器运行Applets程序,微软为了在IE3中支持Applets应用开发了自己虚拟机,这是当时Windows平台下性能最好的Java虚拟机,但是只有Windows版。

Java虚拟机还有很多:JamVM、cacaovm、SableVM、Kaffe、Jelatine JVM、NanoVM、MRP、Moxie JVM、Jikes RVM等。

Java技术展望

模块化

模块化可以使软件部署更加灵活——只部署需要的模块,减小软件体积,模块和模块相互隔离,一个模块不能访问另一个模块的内部类型,这可以有效的减少被攻击的概率。

说起Java模块化,最先提到的一定是OSGi,OSGi最开始是面向嵌入式设备和移动设备的一套将可管理的服务通过网络交付到设备中的开放标准,现在OSGi联盟将OSGi定义为一种技术:一系列用于定义Java动态化组件系统的标准,这些标准通过为大型分布式系统以及嵌入式系统提供一种模块化架构减少了软件的复杂度。

Oracle JDK直到Java 9才支持模块化,名为Java平台模块化系统(JPMS),在实现细节上与OSGi有本质上的区别,JPMS在Java平台自身的模块化方面做的非常好,但是作为模块化的通用解决方案还有很多不足。JPMS可以让OSGi使用起来更简单、更容易。

混合语言

Java虚拟机正在从"Java语言的虚拟机"转变为"多语言虚拟机",每种语言都有其擅长的领域,如果可以在同一个项目中使用不同语言来解决不同问题,并且最终还能运行在同一个虚拟机上,是多么美妙的一件事。现在已经有许多语言可以运行在Java虚拟机上了,如Groovy、Scala、Kotlin等。

多核心并行

虽然在JDK1.5的时候就引入了java.util.concurrent包实现了一个粗粒度的并发框架,在JDK1.7中加入的java.util.concurrent.forkjoin包是对这个框架的一次重要扩充。通过利用Fork/Join模式,可以轻松地利用多个CPU核心来协作完成一个负责的计算任务。JDK1.8提供了Lambda表达式的支持,使Java语言实现了函数式编程,函数式编程的一个重要的优点就是这样的程序天然适合并行运行。

并行计算还必须提及OpenJDK的子项目Sumatra[3],为Java提供了使用GPU和APU运算能力的工具。

除JDK外,还有一些为了满足并行计算的框架,如Apache的Hadoop Map/Reduce等,还出现了一些诸如Scala、Clojure及Erlang等天生具备并行计算能力的语言。

进一步丰富语法

Java 5曾经对Java语法进行过一次扩充,加入了自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环等语法;在Java 7中专门为改进Java语法,在OpenJDK中成立了Coin子项目,做了很多改进,如二进制数的原生支持、在switch语句中支持字符串、"<>"操作符,异常处理的改进简化变成参数方法调用等;在Java 8中提供了Lambda表达式支持。


  1. JDK从1.5版本开始,官方在正式文档与宣传上已经不再使用类似JDK 1.5的命名,只有在程序员内部使用的开发版本号(Developer Version,例如java -version的输出)中才继续沿用1.5、1.6、1.7的版本号,而公开版本号(Product Version)则改为JDK 5、JDK 6、JDK 7的命名方式。

  2. http://openjdk.java.net/projects/jdk/12/

  3. http://openjdk.java.net/projects/sumatra/