1.1、概述
Java不仅仅是一门编程语言,还是一个由一系列计算机软件和规范形成的技术体系,这
个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于嵌入式系
统、移动终端、企业服务器、大型机等各种场合
如下图所示:
Java被认可的原因:
1、拥有一门结构严谨、面向对象的编程语言
2、它摆脱了硬件平台的束缚,实现了“一次编写,到处运行”的理想
3、它提供了一个相对安全的内存管理和访问机制,避免了绝大部分的内存泄露和指针越界问题
4、它实现了热点代码检测和运行时编译及优化,这使得Java应用能随着运行时间的增加而获得更高的性能
5、它有一套完善的应用程序接口,还有无数来自商业机构和开源社区的第三方类库来帮助它实现各种各样的功能…
Java所带来的这些好处使程序的开发效率得到了很大的提升。
1.2、Java技术体系
Sun官方所定义的Java技术体系包括以下几个组成部分:
1、Java程序设计语言
2、各种硬件平台上的Java虚拟机
3、Class文件格式
4、Java API类库
5、来自商业机构和开源社区的第三方Java类库
把Java程序设计语言、Java虚拟机、Java API类库这三部分统称为JDK(Java
Development Kit),JDK是用于支持Java程序开发的最小环境
可以把Java API类库中的Java SE API子集[1]和Java虚拟机这两部分统称为JRE(Java Runtime Environment)
JRE是支持Java程序运行的标准环境。
如下图:
Java技术平台可以分为4个平台:
1、Java Card:支持一些Java小程序(Applets)运行在小内存设备(如智能卡)上的平台
2、Java ME(Micro Edition):支持Java程序运行在移动终端(手机、PDA)上的平台,对
Java API有所精简,并加入了针对移动终端的支持,这个版本以前称为J2ME
3、Java SE(Standard Edition):支持面向桌面级应用(如Windows下的应用程序)的Java
平台,提供了完整的Java核心API,这个版本以前称为J2SE。
4、Java EE(Enterprise Edition):支持使用多层架构的企业应用(如ERP、CRM应用)的
Java平台,除了提供Java SE API外,还对其做了大量的扩充并提供了相关的部署支持,这
个版本称为J2EE。
1.3、Java的发展史
参考:https://cloud.tencent.com/developer/article/1353942
1.4、Java虚拟机历史
1.4.1、Sun Classic/Exact VM
Sun Classic VM的技术可能很原始,这款虚拟机的使命也早已终
结。但仅凭它“世界上第一款商用Java虚拟机”的头衔
1996年1月23日,Sun公司发布JDK 1.0,Java语言首次拥有了商用的正式运行环境,这个
JDK中所带的虚拟机就是Classic VM。这款虚拟机只能使用纯解释器方式来执行Java代码,
如果要使用JIT编译器,就必须进行外挂。但是假如外挂了JIT编译器,JIT编译器就完全接管
了虚拟机的执行系统,解释器便不再工作了。
1.4.2、Sun HotSpot VM
它是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机。
但不一定所有人都知道的是,这个目前看起
来“血统纯正”的虚拟机在最初并非由Sun公司开发,而是由一家名为“Longview
Technologies”的小公司设计的;甚至这个虚拟机最初并非是为Java语言而开发的,它来源于
Strongtalk VM,而这款虚拟机中相当多的技术又是来源于一款支持Self语言实现“达到C语言
50%以上的执行效率”的目标而设计的虚拟机,Sun公司注意到了这款虚拟机在JIT编译上有许
多优秀的理念和实际效果,在1997年收购了Longview Technologies公司,从而获得了HotSpot
VM。
HotSpot VM既继承了Sun之前两款商用虚拟机的优点(如前面提到的准确式内存管
理),也有许多自己新的技术优势,如它名称中的HotSpot指的就是它的热点代码探测技术
(其实两个VM基本上是同时期的独立产品,HotSpot还稍早一些,HotSpot一开始就是准确式
GC,而Exact VM之中也有与HotSpot几乎一样的热点探测。为了Exact VM和HotSpot VM哪个
成为Sun主要支持的VM产品,在Sun公司内部还有过争论,HotSpot打败Exact并不能算技术上
的胜利),HotSpot VM的热点代码探测能力可以通过执行计数器找出最具有编译价值的代
码,然后通知JIT编译器以方法为单位进行编译。如果一个方法被频繁调用,或方法中有效
循环次数很多,将会分别触发标准编译和OSR(栈上替换)编译动作。通过编译器与解释器
恰当地协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无须等待
本地代码输出才能执行程序,即时编译的时间压力也相对减小,这样有助于引入更多的代码
优化技术,输出质量更高的本地代码。
在2006年的JavaOne大会上,Sun公司宣布最终会把Java开源,并在随后的一年,陆续将
JDK的各个部分(其中当然也包括了HotSpot VM)在GPL协议下公开了源码,并在此基础上
建立了OpenJDK。这样,HotSpot VM便成为了Sun JDK和OpenJDK两个实现极度接近的JDK项
目的共同虚拟机。
在2008年和2009年,Oracle公司分别收购了BEA公司和Sun公司,这样Oracle就同时拥有
了两款优秀的Java虚拟机:JRockit VM和HotSpot VM。Oracle公司宣布在不久的将来(大约
应在发布JDK 8的时候)会完成这两款虚拟机的整合工作,使之优势互补。整合的方式大致
上是在HotSpot的基础上,移植JRockit的优秀特性,譬如使用JRockit的垃圾回收器与
MissionControl服务,使用HotSpot的JIT编译器与混合的运行时系统。
1.4.3、Sun Mobile-Embedded VM/Meta-Circular VM
Sun公司所研发的虚拟机可不仅有前面介绍的服务器、桌面领域的商用虚拟机,除此之
外,Sun公司面对移动和嵌入式市场,也发布过虚拟机产品,另外还有一类虚拟机,在设计
之初就没抱有商用的目的,仅仅是用于研究、验证某种技术和观点,又或者是作为一些规范
的标准实现。这些虚拟机对于大部分不从事相关领域开发的Java程序员来说可能比较陌生。
Sun公司发布的其他Java虚拟机有:
(1)KVM
KVM中的K是“Kilobyte”的意思,它强调简单、轻量、高度可移植,但是运行速度比较
慢。在Android、iOS等智能手机操作系统出现前曾经在手机平台上得到非常广泛的应用。
(2)CDC/CLDC HotSpot Implementation
CDC/CLDC全称是Connected(Limited)Device Configuration,在JSR-139/JSR-218规范中
进行定义,它希望在手机、电子书、PDA等设备上建立统一的Java编程接口,而CDC-HI VM
和CLDC-HI VM则是它们的一组参考实现。CDC/CLDC是整个Java ME的重要支柱,但从目前
Android和iOS二分天下的移动数字设备市场看来,在这个领域中,Sun的虚拟机所面临的局
面远不如服务器和桌面领域乐观。
(3)Squawk VM
Squawk VM由Sun公司开发,运行于Sun SPOT(Sun Small Programmable Object
Technology,一种手持的WiFi设备),也曾经运用于Java Card。这是一个Java代码比重很高
的嵌入式虚拟机实现,其中诸如类加载器、字节码验证器、垃圾收集器、解释器、编译器和
线程调度都是Java语言本身完成的,仅仅靠C语言来编写设备I/O和必要的本地代码。
(4)JavaInJava
JavaInJava是Sun公司于1997年~1998年间研发的一个实验室性质的虚拟机,从名字就可
以看出,它试图以Java语言来实现Java语言本身的运行环境,既所谓的“元循环”(MetaCircular,是指使用语言自身来实现其运行环境)。它必须运行在另外一个宿主虚拟机之
上,内部没有JIT编译器,代码只能以解释模式执行。在20世纪末主流Java虚拟机都未能很好
解决性能问题的时代,开发这种项目,其执行速度可想而知。
(5)Maxine VM
Maxine VM和上面的JavaInJava非常相似,它也是一个几乎全部以Java代码实现(只有用
于启动JVM的加载器使用C语言编写)的元循环Java虚拟机。这个项目于2005年开始,到现
在仍然在发展之中,比起JavaInJava,Maxine VM就显得“靠谱”很多,它有先进的JIT编译器和
垃圾收集器(但没有解释器),可在宿主模式或独立模式下执行,其执行效率已经接近了
HotSpot Client VM的水平。
1.4.4、BEA JRockit/IBM J9 VM
前面介绍了Sun公司的各种虚拟机,除了Sun公司以外,其他组织、公司也研发过不少虚
拟机实现,其中规模最大、最著名的就是BEA和IBM公司了。
JRockit VM曾经号称“世界上速度最快的Java虚拟机”(广告词,貌似J9 VM也这样说
过),它是BEA公司在2002年从Appeal Virtual Machines公司收购的虚拟机。BEA公司将其发
展为一款专门为服务器硬件和服务器端应用场景高度优化的虚拟机,由于专注于服务器端应
用,它可以不太关注程序启动速度,因此JRockit内部不包含解析器实现,全部代码都靠即时
编译器编译后执行。除此之外,JRockit的垃圾收集器和MissionControl服务套件等部分的实
现,在众多Java虚拟机中也一直处于领先水平。
IBM J9 VM并不是IBM公司唯一的Java虚拟机,不过是目前其主力发展的Java虚拟机。
IBM J9 VM原本是内部开发代号,正式名称是“IBM Technology for Java Virtual Machine”,简
称IT4J,只是这个名字太拗口了一点,普及程度不如J9。J9 VM最初是由IBM Ottawa实验室
一个名为SmallTalk的虚拟机扩展而来的,当时这个虚拟机有一个bug是由8k值定义错误引起
的,工程师花了很长时间终于发现并解决了这个错误,此后这个版本的虚拟机就称为K8了,
后来扩展出支持Java的虚拟机就被称为J9了。与BEA JRockit专注于服务器端应用不同,IBM
J9的市场定位与Sun HotSpot比较接近,它是一款设计上从服务器端到桌面应用再到嵌入式都
全面考虑的多用途虚拟机,J9的开发目的是作为IBM公司各种Java产品的执行平台,它的主
要市场是和IBM产品(如IBM WebSphere等)搭配以及在IBM AIX和z/OS这些平台上部署Java
应用。
1.4.5、 Azul VM/BEA Liquid VM
我们平时所提及的“高性能Java虚拟机”一般是指HotSpot、JRockit、J9这类在通用平台上
运行的商用虚拟机,但其实Azul VM和BEA Liquid VM这类特定硬件平台专有的虚拟机才
是“高性能”的武器。
Azul VM是Azul Systems公司在HotSpot基础上进行大量改进,运行于Azul Systems公司的
专有硬件Vega系统上的Java虚拟机,每个Azul VM实例都可以管理至少数十个CPU和数百GB
内存的硬件资源,并提供在巨大内存范围内实现可控的GC时间的垃圾收集器、为专有硬件
优化的线程调度等优秀特性。在2010年,Azul Systems公司开始从硬件转向软件,发布了自
己的Zing JVM,可以在通用x86平台上提供接近于Vega系统的特性。
Liquid VM即是现在的JRockit VE(Virtual Edition),它是BEA公司开发的,可以直接运
行在自家Hypervisor系统上的JRockit VM的虚拟化版本,Liquid VM不需要操作系统的支持,
或者说它自己本身实现了一个专用操作系统的必要功能,如文件系统、网络支持等。由虚拟
机越过通用操作系统直接控制硬件可以获得很多好处,如在线程调度时,不需要再进行内核
态/用户态的切换等,这样可以最大限度地发挥硬件的能力,提升Java程序的执行性能。
1.4.6 Apache Harmony/Google Android Dalvik VM
这节介绍的Harmony VM和Dalvik VM只能称做“虚拟机”,而不能称做“Java虚拟机”,但
是这两款虚拟机(以及所代表的技术体系)对最近几年的Java世界产生了非常大的影响和挑
战,甚至有些悲观的评论家认为成熟的Java生态系统有崩溃的可能。
Apache Harmony是一个Apache软件基金会旗下以Apache License协议开源的实际兼容于
JDK 1.5和JDK 1.6的Java程序运行平台,这个介绍相当拗口。它包含自己的虚拟机和Java库,
用户可以在上面运行Eclipse、Tomcat、Maven等常见的Java程序,但是它没有通过TCK认
证,所以我们不得不用那么一长串拗口的语言来介绍它,而不能用一句“Apache的JDK”来说
明。如果一个公司要宣布自己的运行平台“兼容于Java语言”,那就必须要通过
TCK(Technology Compatibility Kit)的兼容性测试。Apache基金会曾要求Sun公司提供TCK的
使用授权,但是一直遭到拒绝,直到Oracle公司收购了Sun公司之后,双方关系越闹越僵,最
终导致Apache愤然退出JCP(Java Community Process)组织,这是目前为止Java社区最严重
的一次“分裂”。
在Sun将JDK开源形成OpenJDK之后,Apache Harmony开源的优势被极大地削弱,甚至连
Harmony项目的最大参与者IBM公司也宣布辞去Harmony项目管理主席的职位,并参与
OpenJDK项目的开发。虽然Harmony没有经过真正大规模的商业运用,但是它的许多代码
(基本上是Java库部分的代码)被吸纳进IBM的JDK 7实现及Google Android SDK之中,尤其
是对Android的发展起到了很大的推动作用。
说到Android,这个时下最热门的移动数码设备平台在最近几年间的发展过程中所取得
的成果已经远远超越了Java ME在过去十多年所获得的成果,Android让Java语言真正走进了
移动数码设备领域,只是走的并非Sun公司原本想象的那一条路。
Dalvik VM是Android平台的核心组成部分之一,它的名字来源于冰岛一个名为Dalvik的
小渔村。Dalvik VM并不是一个Java虚拟机,它没有遵循Java虚拟机规范,不能直接执行Java
的Class文件,使用的是寄存器架构而不是JVM中常见的栈架构。但是它与Java又有着千丝万
缕的联系,它执行的dex(Dalvik Executable)文件可以通过Class文件转化而来,使用Java语
法编写应用程序,可以直接使用大部分的Java API等。目前Dalvik VM随着Android一起处于
迅猛发展阶段,在Android 2.2中已提供即时编译器实现,在执行性能上有了很大的提高。
1.4.7 Microsoft JVM及其他
在十几年的Java虚拟机发展过程中,除去上面介绍的那些被大规模商业应用过的Java虚
拟机外,还有许多虚拟机是不为人知的或者曾经“绚丽”过但最终湮灭的。我们以其中微软公
司的JVM为例来介绍一下。
也许Java程序员听起来可能会觉得惊讶,微软公司曾经是Java技术的铁杆支持者(也必
须承认,与Sun公司争夺Java的控制权,令Java从跨平台技术变为绑定在Windows上的技术是
微软公司的主要目的)。在Java语言诞生的初期(1996年~1998年,以JDK 1.2发布为分
界),它的主要应用之一是在浏览器中运行Java Applets程序,微软公司为了在IE3中支持
Java Applets应用而开发了自己的Java虚拟机,虽然这款虚拟机只有Windows平台的版本,却
是当时Windows下性能最好的Java虚拟机,它在1997年和1998年连续两年获得了《PC
Magazine》杂志的“编辑选择奖”。但好景不长,在1997年10月,Sun公司正式以侵犯商标、不
正当竞争等罪名控告微软公司,在随后对微软公司的垄断调查之中,这款虚拟机也曾作为证
据之一被呈送法庭。这场官司的结果是微软公司赔偿2000万美金给Sun公司(最终微软公司
因垄断赔偿给Sun公司的总金额高达10亿美元),承诺终止其Java虚拟机的发展,并逐步在
产品中移除Java虚拟机相关功能。具有讽刺意味的是,到最后在Windows XP SP3中Java虚拟
机被完全抹去的时候,Sun公司却又到处登报希望微软公司不要这样做[1]。Windows XP高级
产品经理Jim Cullinan称:“我们花费了3年的时间和Sun打官司,当时他们试图阻止我们在
Windows中支持Java,现在我们这样做了,可他们又在抱怨,这太具有讽刺意味了。”
我们试想一下,如果当年Sun公司没有起诉微软公司,微软公司继续保持着对Java技术
的热情,那Java的世界会变得怎么样呢?.NET技术是否会发展起来?但历史是没有假设的。
其他在本节中没有介绍到的Java虚拟机还有(当然,应该还有很多笔者所不知道的):
JamVM.
cacaovm.
SableVM.
Kaffe.
Jelatine JVM.
NanoVM.
MRP.
Moxie JVM.
Jikes RVM
1.5、Java技术的未来
1.5.1 模块化
模块化是解决应用系统与技术平台越来越复杂、越来越庞大问题的一个重要途径。无论
是开发人员还是产品最终用户,都不希望为了系统中一小块的功能而不得不下载、安装、部
署及维护整套庞大的系统。站在整个软件工业化的高度来看,模块化是建立各种功能的标准
件的前提。最近几年OSGi技术的迅速发展、各个厂商在JCP中对模块化规范的激烈斗争,
都能充分说明模块化技术的迫切和重要。
1.5.2 混合语言
当单一的Java开发已经无法满足当前软件的复杂需求时,越来越多基于Java虚拟机的语
言开发被应用到软件项目中,Java平台上的多语言混合编程正成为主流,每种语言都可以针
对自己擅长的方面更好地解决问题。试想一下,在一个项目之中,并行处理用Clojure语言编
写,展示层使用JRuby/Rails,中间层则是Java,每个应用层都将使用不同的编程语言来完
成,而且,接口对每一层的开发者都是透明的,各种语言之间的交互不存在任何困难,就像
使用自己语言的原生API一样方便[1],因为它们最终都运行在一个虚拟机之上。
在最近的几年里,Clojure、JRuby、Groovy等新生语言的使用人数不断增长,而运行在
Java虚拟机(JVM)之上的语言数量也在迅速膨胀,图1-4中列举了其中的一部分。这两点证
明混合编程在我们身边已经有所应用并被广泛认可。通过特定领域的语言去解决特定领域的
问题是当前软件开发应对日趋复杂的项目需求的一个方向
除了催生出大量的新语言外,许多已经有很长历史的程序语言也出现了基于Java虚拟机
实现的版本,这样使得混合编程对许多以前使用其他语言的“老”程序员也具备相当大的吸引
力,软件企业投入了大量资本的现有代码资产也能很好地保护起来。表1-1中列举了常见语
言的JVM实现版本。
对这些运行于Java虚拟机之上、Java之外的语言,来自系统级的、底层的支持正在迅速
增强,以JSR-292为核心的一系列项目和功能改进(如Da Vinci Machine项目、Nashorn引擎、
InvokeDynamic指令、java.lang.invoke包等),推动Java虚拟机从“Java语言的虚拟机”向“多语
言虚拟机”的方向发展。
1.5.3 多核并行
CPU硬件的发展方向已经从高频率转变为多核心,随着多核时代的来临,软件开
发越来越关注并行编程的领域。早在JDK 1.5就已经引入java.util.concurrent包实现了一个粗粒
度的并发框架。而JDK 1.7中加入的java.util.concurrent.forkjoin包则是对这个框架的一次重要
扩充。Fork/Join模式是处理并行编程的一个经典方法,如图1-5所示。虽然不能解决所有的问
题,但是在此模式的适用范围之内,能够轻松地利用多个CPU核心提供的计算资源来协作完
成一个复杂的计算任务。通过利用Fork/Join模式,我们能够更加顺畅地过渡到多核时代。
在Java 8中,将会提供Lambda支持,这将会极大改善目前Java语言不适合函数式编程的
现状(目前Java语言使用函数式编程并不是不可以,只是会显得很臃肿),函数式编程的一
个重要优点就是这样的程序天然地适合并行运行,这对Java语言在多核时代继续保持主流语
言的地位有很大帮助。
另外,在并行计算中必须提及的还有OpenJDK的子项目Sumatra目前显卡的算术运算
能力、并行能力已经远远超过了CPU,在图形领域以外发掘显卡的潜力是近几年计算机发展
的方向之一,例如C语言的CUDA。Sumatra项目就是为Java提供使用GPU(Graphics
Processing Units)和APU(Accelerated Processing Units)运算能力的工具,以后它将会直接提
供Java语言层面的API,或者为Lambda和其他JVM语言提供底层的并行运算支持。
在JDK外围,也出现了专为满足并行计算需求的计算框架,如Apache的Hadoop
Map/Reduce,这是一个简单易懂的并行框架,能够运行在由上千个商用机器组成的大型集群
上,并且能以一种可靠的容错方式并行处理TB级别的数据集。另外,还出现了诸如Scala、
Clojure及Erlang等天生就具备并行计算能力的语言。
1.5.4 进一步丰富语法
Java 5曾经对Java语法进行了一次扩充,这次扩充加入了自动装箱、泛型、动态注解、
枚举、可变长参数、遍历循环等语法,使得Java语言的精确性和易用性有了很大的进步。在
Java 7(由于进度压力,许多改进已推迟至Java 8)中,对Java语法进行了另一次大规模的扩
充。Sun(已被Oracle收购)专门为改进Java语法在OpenJDK中建立了Coin子项目[1]来统一处
理对Java语法的细节修改,如二进制数的原生支持、在switch语句中支持字符串、“<>”操
作符、异常处理的改进、简化变长参数方法调用、面向资源的try-catch-finally语句等都是在
Coin项目之中提交的内容
1.5.5 64位虚拟机
主流的CPU就开始支持64位架构了。Java虚拟机也在很早之前就推出了支
持64位系统的版本。但Java程序运行在64位虚拟机上需要付出比较大的额外代价:首先是内
存问题,由于指针膨胀和各种数据类型对齐补白的原因,运行于64位系统上的Java应用需要
消耗更多的内存,通常要比32位系统额外增加10%~30%的内存消耗;其次,多个机构的测
试结果显示,64位虚拟机的运行速度在各个测试项中几乎全面落后于32位虚拟机,两者大约
有15%左右的性能差距。
但是在Java EE方面,企业级应用经常需要使用超过4GB的内存,对于64位虚拟机的需求
是非常迫切的,但由于上述原因,许多企业应用都仍然选择使用虚拟集群等方式继续在32位
虚拟机中进行部署。Sun也注意到了这些问题,并做出了一些改善,在JDK 1.6 Update 14之
后,提供了普通对象指针压缩功能(-XX:+UseCompressedOops,这个参数不建议显式设
置,建议维持默认由虚拟机的Ergonomics机制自动开启),在执行代码时,动态植入压缩指
令以节省内存消耗,但是开启压缩指针会增加执行代码数量,因为所有在Java堆里的、指向
Java堆内对象的指针都会被压缩,这些指针的访问就需要更多的代码才可以实现,而且并不
只是读写字段才受影响,在实例方法调用、子类型检查等操作中也受影响,因为对象实例指
向对象类型的引用也被压缩了。随着硬件的进一步发展,计算机终究会完全过渡到64位的时
代,这是一件毫无疑问的事情,主流的虚拟机应用也终究会从32位发展至64位,而虚拟机对
64位的支持也将会进一步完善。
JDK8的新特性:
1、接口的默认方法和静态方法:
java8中使用两个新概念扩展类接口含义,默认方法和静态方法,默认方法使得开发者可以在
不破坏二进制兼容性的情况下,往现存的接口中添加新的方法,即不强制那些实现该接口的类
也同时实现这个新加的方法
2、Lambda表达式和函数式编程
3、Date API
4、重复注解
5、更好的类型推断
java8编辑器在类型推断方面有很大的提升,在很多场景下可以推导某个参数的数据类型
从而使得代码更为简介
6、Nashorn JavaScript引擎