自1946年2月14日世界上首款计算机问世,第一代计算机语言“机器语言”便诞生了,它使用的是最原始的穿孔卡片,这种卡片上使用的语言只有专家才能理解,与人类语言差别极大。这种语言本质上是计算机能识别的唯一语言,人类很难理解。为了能让人们更容易理解并编写,于是便有了第二代的“汇编语言”,相比机器语言,汇编语言大大前进了一步,尽管它还是太复杂,人们在使用时很容易出错误,但毕竟许多数码已经开始用字母来代替。简单的“0、1”数码谁也不会理解,但字母是人们能够阅读并拼写的。虽然第二代计算机语言仍然是“面向机器”的语言,但它已注定成为机器语言向更高级语言进化的桥梁。当计算机语言发展到第三代时,就进入了“面向人类”的语言阶段。你可以阅读、并直接用人类的语言来输入。对我们汉语来说,目前还不能用中文汉字来输入指令,这主要是因为中文的输入还没有一个非常好的手段。第三代语言被人们称之为“高级语言”。高级语言是一种接近于人们使用习惯的程序设计语言。它允许用英文写计算程序,程序中所使用的运算符号和运算式子,都和我们日常用的数学式子差不多。高级语言容易学习,通用性强,书写出的程序比较短,便于推广和交流,是很理想的一种程序设计语言。今天的主角是第三代语言“高级语言“中的Java语言。
Java的技术体系
从广义上讲,Clojure,JRuby,Groovy等运行于Java虚拟机上的语言及其相关的程序都属于Java技术体系的一员,如果仅从传统意义上来看,Sun官方所定义的Java技术体系包括以下几个部分
- Java程序设计语言
- 各种硬件平台上的Java虚拟机
- Class文件格式
- Java API类库
- 来自商业机构和开源社区的第三方Java类库
我们可以把Java程序设计语言,Java虚拟机,Java API类库这三个部分统称为JDK(Java Development Kit),JDK是用于支持Java程序开发的最小环境,如果单单只是运行Java程序,那么JRE就足够了。如果按照技术所服务的领域来划分,或者说按照Java技术关注的重点业务领域来划分,Java技术体系可以分为4个平台
- Java Card:支持一些Java小程序(Applets)运行在小内存设备(如智能卡)上的平台
- Java ME(Micro Edition):支持Java程序运行在移动端(手机,PDA)上的平台,对Java API有所精简,并加入了针对移动端的支持
- Java SE(Standard Edition):支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java 核心API
- Java EE(Enterprise Edition):支持使用多层架构的企业级应用(如ERP,CRM应用)的Java平台,除了提供Java SE API外,还对其做了大量的扩充并提供了相关的部署支持
Java发展史
从第一个Java版本诞生到现在已有24年,沧海桑田一瞬间,转眼24年过去了,Java依旧火热,在这20多年里诞生了无数和Java相关的产品,技术和标准,让我们走入时间隧道,从孕育Java语言的时代开始,回顾一下Java的发展轨迹和历史变迁
-
绿色计划
由詹姆斯·高斯林(James Gosling)博士领导的绿色计划(Green Project)开始启动,此计划的目的是开发一种能够在各种消费性电子产品(如机顶盒,冰箱,收音机)上运行的程序架构。这个计划的产品就是Java语言的前身:Oak(橡树)。Oak当时在消费市场上并不算成功,但随着1996年互联网潮流的兴起,Oak迅速找到了最合适自己发展的市场定位并蜕变成为Java语言
-
Java诞生
Oak语言改名为Java,并且在SunWorld大会上正式发布Java 1.0版本。标准着Java的诞生,Java语言第一次提出了我们现在熟知的“Write Once,Run Anywhere”口号
-
JDK 1.0发布
第一个正式版本,JDK 1.0发布,Java语言有了第一个正式版本的运行环境。JDK 1.0提供了一个纯解释执行的Java虚拟机实现(Sun Classic VM)。JDK 1.0版本的代表技术包括:Java虚拟机,Applet,AWT等
同年4月,10个最主要的操作系统供应商申明将在其产品中嵌入Java技术。同年9月,已有大约8.3万网页应用了Java技术来制作。在1996年5月底,Sun公司于美国旧金山就行了首届JavaOne大会,从此JavaOne成为全世界数百万Java语言开发者一年一度的技术盛会
-
JDK 1.1发布
Sun公司发布了JDK 1.1,Java技术的一些最基础的支持点(如JDBC等)都是在JDK 1.1版本中发布,JDK 1.1版的技术代表有:JAR文件格式,JDBC,JavaBeans,RMI。Java语法也有了一定的发展,如内部类(Inner Class)和反射(Reflection)都是在这个时候出现
直到1999年4月8日,JDK 1.1一共发布了 1.1.0 ~ 1.1.8九个版本。从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(切尔西,城市名)
-
JDK 1.2发布
JDK迎来了一个里程碑式的版本JDK 1.2,工程代号为Playground(竞技场),Sun在这个版本中把Java技术拆分为3个方向,分别是面向桌面应用开发的J2SE(Java 2 Platform, Standard Edition),面向企业级开发的J2EE(Java 2 Platform, Enterprise Edition)和面向手机等移动终端开发的J2ME(Java 2 Platform, Micro Edition)。在这个版本中出现的代表性的技术非常多,如EJB,Java Plug-in,Java IDL,Swing等。并且这个版本中Java虚拟机第一次内置了JIT(Just In Time)编译器。JDK 1.2中曾并存过3个虚拟机,Classic VM,HotSpot VM和Exact VM,其中Exact VM只在Solaris平台出现过,HotSpot VM和Exact VM两个虚拟机都是内置JIT编译器,而之前版本所带的Classic VM只能以外挂的形式使用JIT编译器。在语言和API级别上,Java添加了 strictfp关键字与Java编码之中极为常用的Collections集合类。在1993年3月和7月,分别有JDK 1.2.1和JDK 1.2.2两个小版本发布
-
HotSpot虚拟机发布
HotSpot虚拟机发布,HotSpot最初由一家名为“Longview Tecnologies”的小公司开发,因为HotSpot的优异表现,这家公司在1997年被Sun公司收购了。HotSpot虚拟机发布时是作为JDK 1.2的附加程序提供的,后来它成为了JDK 1.3及以后所有版本的Sun JDK的默认虚拟机
-
JDK 1.3发布
工程代号为Kestrel(美国红隼)的JDK 1.3发布,JDK 1.3相对于JDK 1.2的改进主要表现在一些类库上(如数学运算和新的Timer API等),JNDI服务从JDK 1.3开始被作为一项平台级服务提供(以前JNDI仅仅是一项扩展),使用CORBA IIOP来实现RMI的通信协议,等等。这个版本还对Java 2D做了end改进,提供了大量心得Java 2D API,并且添加了JavaSound类库。JDK 1.3有1个修正版本JDK 1.3.1,工程代号为Ladybird(瓢虫),于2001年5月17日发布。自JDK 1.3开始,Sun维持了一个习惯:大约每隔两年发布一个JDK的主版本,以动物命名,期间发布的各个修正版本则以昆虫作为工程代号
-
JDK 1.4发布
工程代号为Merlin(灰背隼)。JDK 1.4是Java真正走向成熟的一个版本,Compaq,Funjitsu,SAS,Symbian,IBM等著名公司都有参与甚至实现自己独立的JDK 1.4。哪怕是在十多年后的今天,仍有许多主流应用(Spring,Hibernate,Struts等)能直接运行在JDK 1.4之上。或者继续发布能运行在JDK 1.4上的版本JDK 1.4同样发布了很多新的技术特性,如正则表达式,异常链,NIO,日志类,XML解析器和XSLT转换器等。JDK 1.4有两个后续修正版:2002年9月16日发布的工程代号为Grasshopper(蚱蜢)的JDK 1.4.1和2003年6月26日发布的工程代号为Mantis(螳螂)的JDK 1.4.2
2002年前后还发生了一件与Java没有直接关系,但事实上对Java的发展进程影响很大的事件,那就是微软公司的 .NET Framework发布了。这个无论是技术实现上还是目标用户上都与Java有很多相近之处的技术平台给Java带来了很多讨论,比较和竞争。 .NET平台和Java平台之间声势浩大的孰优孰劣的论战
-
JDK 1.5发布
工程代号为Tiger(老虎)。从JDK 1.2以来,Java在语法层面上的变换一直很小,而JDK 1.5在Java语法易用性上做出来非常大的改进。例如自动装箱,泛型,动态注解,美剧,可变长参数,遍历循环(foreach循环)等语法特性都是在JDK 1.5中加入的。在虚拟机和API层面上,这个版本改进了Java的内存模型(Java Memory Model,JMM),提供了java.util.concurrent并发包等。另外JDK 1.5是官方声明可以支持Windows 9x平台的最后一个JDK版本
-
JDK 1.6发布
工程代号Mustang(野马)。在这个版本中,Sun终结了从JDK 1.2开始已有8年历史的 J2EE,J2SE,J2ME的命名方式,启用Java SE 6,Java EE 6,Java ME 6的命名方式。JDK 1.6的改进包括:提供动态语言支持(通过内置Mozilla JavaSceipt Rhino引擎实现,一个完全以Java编写的JavaScript引擎,可在java代码中调用javascript脚本),提供编译API和微型HTTP服务器API等,同时这个版本对Java虚拟机内部做了大量改进,包括锁与同步,垃圾收集,类加载等方面的算法都有相当多的改动
在2006年11月13日的JavaOne大会上,Sun公司宣布最终将Java开源,并在随后的一年多内,陆续将JDK的各个部分在GPL v2(GUN General Public License v2)协议下公开了源码,并建立了OpenJDK组织对这些源码进行独立管理,除了极少量的产权代码(Encumbered Code,这部分代码大多是Sun本身也无权限进行开源处理的)外,OpenJDK几乎包括了Sun JDK的全部代码,OpenJDK的质量主管曾表示,在JDK 1.7中,Sun JDK和OpenJDK除了代码文件头的版权注释外,代码基本上完全一样,所以OpenJDK 7与Sun JDK 1.7本质上是同一套代码库开发的产品
JDK 1.6发布以后,由于代码复杂性的增加,JDK开源,开发JavaFX,经济危机及Sun收购案等原因,Sun在JDK发展以外的事情上耗费了很多资源,JDK的更新没有在维持两年发布一个主版本的发展速度。JDK 1.6到目前为止一共发不了37个Update版本,最新版本为 Java SE 6 Update 37,与2012年10月16日发布
-
Oracle收购Sun
Oracle公司宣布正式以74亿美元的价格收购Sun公司,Java商标从此正式归Oracle所有(Java语言本身并不属于哪个公司所有,它由JCP组织进行管理,尽管JCP主要是有Sun公司或者说Oracle公司所领导的)。由于此前Oracle公司已经收购了另外一家大型的中间件企业BEA公司,在完成对Sun公司的收购后,Oracle公司分别从BEA和Sun中取得了目前三大商业虚拟机中的两个:JRockit和HotSpot,Oracle公司宣布在未来的1到2年内,将把这两个优秀的虚拟机互相取长补短,最终合二为一。可以预见在不久的将来,Java虚拟机技术将会产生相当巨大的变化
-
JDK 1.7发布
工程代号为Dolphin(海豚)的JDK 1.7完成了其第一个里程碑版本。根据JDK 1.7的功能规划,一共设置了10个里程碑。最后一个里程碑版本原计划于2010年9月9日结束,但由于各种原因,JDK 1.7最终无法按计划完成
从JDK 1.7最开始的功能规划来看,它本应是一个包含许多重要改进的JDK版本,其中的Lambda项目(Lambda表达式,函数式编程),Jigsaw项目(虚拟机模块化支持),动态语言支持,GarbageFirst收集器和Coin项目(语言细节优化)等子项目对于Java业界都会产生深远的影响。在JDK 1.7开发期间,Sun公司由于相继在技术竞争和商业竞争上陷入泥潭,公司的股票市值跌至巅峰时期的3%,已无力推动JDK 1.7的研发工作按正常计划进行。为了尽快结束JDK 1.7长期“跳票”的问题,Oracle公司收购Sun公司后不久便宣布将实行“B计划”,大幅裁剪JDK 1.7的预定目标,以保证JDK 1.7的研发工作按正常计划进行。“B计划”把不能按时完成的Lambda项目,Jigsaw项目和Coin项目的部分改进延迟到JDK 1.8中。最终,JDK 1.7的主要改进包括:提供新的G1收集器(G1在发布时依然处于Experimental状态,直到2012年4月的Update 4中在正式“转正”),加强对非Java语言的调用支持(JSR-292),升级类加载架构等
到目前为止,JDK 1.7已经发布了9个版本Update版本,从Java SE 7 Update 4起,Oracle开始支持Mac OS X操作系统,并且在Update 6中达到完全支持的程度。同时,在Update 6中还对ARM指令架构提供了支持。至此,官方提供的JDK可以运行于Windows,Linux,Solaris和Mac OS平台上,支持ARM,x86,x64和Sparc指令集架构类型
-
JDK 1.8发布
工程代号为Spider(蜘蛛)的JDK 1.8发布,是JDK的一个重要版本。完成了在JDK 1.7中未完成的Lambda功能,Java从此支持函数式编程,并提供了强大的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。在JDK 1.8中使用Nashorn引擎开始取代此前一直使用的Rhino引擎(JDK6、7中)成为JDK的嵌入式JavaScript引擎,它将JS代码编译为Java字节码,与先前的Rhino的实现相比,性能提升了2到10倍。此外还提供了新的日期API和Optional类(用来解决空指针异常)
-
JDK 1.9发布
支持平台级模块系统,当启动一个模块化应用时, JVM 会验证是否所有的模块都能使用,这基于 `requires` 语句——比脆弱的类路径迈进了一大步。模块允许你更好地强制结构化封装你的应用并明确依赖。此外使用HTTP 2 Client 支持 HTTP 2.0 和 WebSockets,替代传统的 HttpURLConnection。Process API 更新 提升对操作系统进程的控制和管理。Java 的本地接口也被重新作为 Java Native Runtime project 的一部分,将支持多 GB 堆和一个自调整的 JVM。许多语言已经具有交互式编程环境,Java 现在加入了这个俱乐部。在JDK 19中可以从控制台启动 Jshell ,并直接启动输入和执行 Java 代码。 Jshell 的即时反馈使它成为探索 API 和尝试语言特性的好工具。
Java虚拟机发展史
前文我们以整个Java技术的角度观察了Java技术的发展,许多开发者都会潜意识的把它与Sun公司的HotSpot虚拟机等同看待,也许会注意到BEA JRockit和IBM J9,但对JVM的认识不仅仅只有这些。从1996年初Sun公司发布的JDK 1.0中所包含的Sun Classic VM到今天,曾经涌现,湮灭过许多或经典或优秀或有特色的虚拟机实现,在这,我们暂且把代码技术放下,回顾一下Java虚拟机家族的发展轨迹和历史变迁
-
初代版虚拟机 Classic VM
从今天的视角来看,Sun Classic VM的技术可能很原始,这款虚拟机的使命也早已终结。但仅凭它“世界第一款商用Java虚拟机”的头衔,就足够有让历史记住它的理由
1996年1月23日,Sun公司发布JDK 1.0,Java首次拥有了商用的正式运行环境,这个JDK中所带的虚拟机就是Classic VM。这款虚拟机只能使用纯解释器方式来执行Java代码,如果使用JIT编译器,就必须使用外挂,但是假如外挂了JIT编译器,JIT编译器就完全接管了虚拟机的执行系统,解释器便不再工作了。由于这时的虚拟机需要解释执行代码,因此这个阶段即使使用了JIT编译器输出本地代码,执行效率也和传统的C/C++程序有很大差距,“Java很慢”的形象就在此时树立了
-
昙花一现的 Exact VM
为了解决Classic VM所面临的各种问题,提升运行效率。在JDK 1.2时,曾在Solaris平台上发布过一款名为 Exact VM的虚拟机,它的执行系统已经具备现代高性能虚拟机的雏形:如两级即时编译器,编译器与解释器混合工作模式。Exact VM因它使用准确式内存管理(Exact Memory Management)而得名,即虚拟机可以知道内存中某个位置的数据具体是什么类型
虽然Exact VM的技术相对Classic VM来说先进很多,但是在商业应用上只存在了很短暂的时间就被更优秀的HotSpot VM所取代,甚至还没来得及发布Windows和Linux平台下的商用版本,而Classic VM的生命周期相对长了许多,它在JDK 1.2之前是Sun JDK中唯一的虚拟机,在JDK 1.2时,它与HotSpot VM并存
-
现在的主流 HotSpot VM
提起HotSpot VM,相信所有Java开发者都知道,它是Sun JDK和OpenJDK中所带的虚拟机,是现在JDK默认使用的虚拟机,也是目前使用范围最广的Java虚拟机。但不一定所有人都知道的是,这个目前看来“血统纯正”的虚拟机在最初并非由Sun公司开发,而是由一家名为“Longview Technologies”的小公司设计的。甚至最初这个虚拟机并非是为Java语言而开发的。它源于Strongtalk VM,而这款虚拟机中相当多的技术又是来源于一款支持Self语言实现“达到C语言50%以上执行效率”的目标而设计的虚拟机
Sun公司注意到了这款虚拟机在JIT编译上有许多优秀的理念和实际效果,在1997年收购了Longview Technologies公司,从而获得了HotSpot VM。HotSpot VM既继承了Sun之前两款商用虚拟机的优点(如Exact VM的准确式内存管理),也有许多自己新的技术优势,如它名称中的HotSpot指的就是它的热点代码探测技术
-
高性能的 JRockit VM
除了Sun公司以外,其他组织和公司也研发过不少虚拟机实现,其中就有BEA公司和IBM公司了,JRockit VM曾经号称“世界上速度最快的Java虚拟机”,它是BEA公司在2002年从Appeal Virtual Machines公司收购的虚拟机,由于专注于服务器端应用,它可以不太关注程序启动速度,因此JRockit内部不包含解析器实现,全部代码靠即时编译器编译后执行。除此之外JRockit的垃圾收集器和MissionControl服务套件等部分的实现,在众多Java虚拟机中也一直处于领先水平
-
IBM J9 VM
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比较接近,它是一款设计上从服务器端到桌面应用再到嵌入式都全面考虑的多用途虚拟机
-
特定硬件平台的 Azul VM
我们平时所提及的“高性能Java虚拟机”一般指 HotSpot,JRockit,J9这类在通用平台上运行的商用虚拟机,但其实Azul VM这类特定硬件平台专有的虚拟机才是“高性能”的武器
Azul VM是Azul Systems公司在HotSpot基础上进行了大量改进,运行于Azul Systems公司的专有硬件Vega系统上的Java虚拟机,每个Azul VM实例都可以管理至少数十个CPU和数百GB内存硬件资源,并提供在巨大内存范围内实行可控的GC时间的垃圾收集器,为专有硬件优化的线程调度等优秀特性。在2010年,Azul Systems公司开始从硬件转向软件,发布了自己的Zing JVM,可以在通用的x86平台上提供接近于Vega系统的特性
-
可访问硬件的 EBA Liquid VM
Liquid VM即是现在的JRockit VE(Virtual Edition),它是EBA公司开发的,可以直接运行在自家Hypervisor系统上的JRockit VM的虚拟化版本,Liquid VM不需要操作系统的支持,或者说他自己本身实现了一个专用操作系统的必要功能,如文件系统,网络支持等,由虚拟机越过通用操作系统直接控制硬件可以获得很多好处,如在线程调度时,不需要再进行内核态/用户态的切换等,这样可以最大限度的发挥硬件能力,提升Java程序的执行性能
-
Apache Harmony VM
Apache Harmony VM是一个Apache软件基金会旗下以Apache License协议开源的实际兼容于JDK 1.5和JDK 1.6的Java程序运行平台,这个介绍相当拗口,它包含自己的虚拟机和Java库,用户就可以在上面运行Eclipse,Tomcat,Maven等常见的Java程序,但它没有通过TCK认证。如果一个公司要宣布自己的运行平台“兼容于Java语言”,那么就必须要通过TCK认证的兼容性测试。Apache基金会曾要求Sun公司提供TCK的使用授权,但是一直遭到拒绝,直到Oracle公司收购了Sun公司之后,双方关系越闹越僵,最终导致Apache愤然退出JCP(Java Community Process)组织,这是目前为止Java社区最严重的一次“分裂”
-
移动端虚拟机Google Android Dalvik VM
在Sun将JDK开源形成OpenJDK之后,Apache Harmony开源的优势被极大的削弱,甚至连Harmony项目的最大参与者IBM公司也宣布辞去Harmony项目管理主席的职位,并参与OpenJDK项目的开发。虽然Harmony没有真正大规模的商业运用,但它的许多代码被吸纳进IBM的JDK 7实现和Google Android SDK之中,尤其对Android的发展起到了很大的推动作用
如今Android已牢牢占据移动端的统治地位,Android让Java语言真正走进了移动数码设备的领域,只是走的并非Sun公司原本想象的那一条路,其成果已经远远超越了Java ME在过去十多年所获得的成果
Dalvik VM是Android平台的核心组件之一,它的名字源于冰岛一个名为Dalvik的小渔村。Dalvik VM并不是一个Java虚拟机,它没有遵循Java虚拟机规范,不能直接执行Java的Class文件,使用的是寄存器架构而不是JVM常见的栈架构。但它又与Java有着千丝万缕的关系,它指向的dex(Dalvik Executable)文件可以通过Class文件转化而来,使用Java语法编写应用程序,可以直接使用大部分的Java API等。目前Dalvik VM随着Android一起处于迅猛发展阶段
-
支持在浏览器运行Java的 Microsoft 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》杂志的“编辑选择奖”
关于Microsoft JVM还发生了一次影响Java发展的事件,当时Microsoft JVM发展正好,但在1997年10月,Sun公司正式以侵犯商标,不正当竞争等罪名控告微软公司,在随后对微软公司的垄断调查之中吗,这款虚拟机也曾作为证据之一被呈送法庭。这场官司的结果是微软公司赔偿2000万美金给Sun公司(最终微软公司因垄断赔偿Sun公司的总金额高达10亿美元),并承诺终止其Java虚拟机的发展,并逐渐在产品中移除Java虚拟机的相关功能。具有讽刺意味的是,到最后在Windows XP SP3中Java虚拟机被完全抹去的时候,Sun公司却又到处登报希望微软公司不要这样做。Windows XP高级产品经理 Jim Cullinan称:“我们花费了3年的实际和Sun打官司,当时他们试图阻止我们在Windows中支持Java,现在我们这样做了,可他们又在抱怨,这太具有讽刺意味了”
我们试想一下,当时的微软想在Windows系统上绑定Java,以Windows操作系统的迅猛发展程度,对于Java的推广有很大的帮助。如果当年Sun公司没有起诉微软公司,微软公司继续保持着对Java技术的热情,那Java的世界会变成什么样呢?