Skip to content

基础知识

简介

JVM(Java Virtual Machine,Java 虚拟机)是 Java 程序运行的核心组件。JVM 负责将 Java 字节码文件解释执行,提供了 Java 语言的跨平台特性。

时至今日,Java 已经成为一门广泛应用的编程语言,不仅仅是因为其结构严谨、面向对象,还有许多不可忽视的特点:摆脱硬件平台的束缚,实现“一次编写,到处运行”的理想; 自动内存管理,避免了 C/C++ 等语言中的内存泄漏和指针越界访问等问题;强大的类库支持,提供了丰富的 API,方便开发者快速构建应用程序......

Java 技术体系

从广义上讲,所有符合《Java 语言规范(Java Language Specification)》的实现(如:Kotlin、Groovy 等)都是 Java 技术体系中的一员。

从传统意义上讲,JCP(Java Community Process,Java 社区)所定义的 Java 技术体系包括以下几个部分:

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

根据 Java 各个组成部分的功能来划分,Java 程序设计语言、Java 虚拟机和 Java 类库这三个部分统称为 JDK(Java Development Kit,Java 开发工具包),JDK 是用于支持 Java 程序开发的最小环境。 把 Java 类库 API 中的 Java SE API 子集和 Java 虚拟机这两个部分统称为 JRE(Java Runtime Environment,Java 运行环境),JRE 是用于支持 Java 程序运行的标准环境。

按照技术所服务的领域或者技术所关注的重点业务来划分,Java 技术体系可以划分为以下四条产品线:

  • Java Card:用于支持 Java 小程序(Applet)、智能卡等小型设备运行的平台。
  • Java ME(Micro Edition):用于支持移动设备、嵌入式设备运行的平台。需要注意的是 Android 平台不属于 Java ME。
  • Java SE(Standard Edition):用于支持桌面应用程序、服务器端应用程序等运行的平台。这条产品线在 JDK 6 之前被称为 J2SE。
  • Java EE(Enterprise Edition):用于支持企业级应用程序(如 ERP、MIS、CRM 应用)运行的平台。这条产品线在 JDK 6 以前被称为 J2EE,在 JDK 10 以后被 Oracle 放弃,捐献给 Eclipse 基金会管理,此后被称为 Jakarta EE。

24121401.png

图 Java 技术体系所包括的内容

Java 发展史

  • 1991 年 4 月,由 James Gosling 领导的绿色计划(Green Project)开始启动,计划的最初目标是开发一种嵌入式语言,用于各种消费性电子产品(如电视机、电话等)的控制。这种语言最初被命名为 Oak(得名于 James Gosling 办公室外的一棵橡树)。 起初,Oak 在当时的环境下并没有引起太多的关注,但随着 1995 年互联网潮流的兴起,Oak 逐渐被重新定位为一种用于开发互联网应用程序的语言。为了更好地适应这种新的定位,Oak 也被重新命名为 Java。

  • 1995 年 5 月 23 日,Oak 语言改名为 Java,Sun 公司正式发布了 Java 1.0 版本,Java 语言第一次提出了“Write Once, Run Anywhere”(一次编写,到处运行)的理念,这也是 Java 语言的一大特色。

  • 1996 年 1 月 23 日,JDK 1.0 发布,提供了一个纯解释执行的 Java 虚拟机实现(Sun Classic VM),Java 语言有了第一个正式版本的运行环境。

  • 1997 年 2 月 19 日,Sun 公司发布了 JDK 1.1,技术代表有:JAR 文件格式、JDBC、JavaBeans、RMI 等,在 Java 语言语法上也有所增强,如内部类(Inner Class)和反射(Reflection)等。

  • 1998 年 12 月 4 日,JDK 1.2 发布,工程代号为 PlayGround(竞技场)。作为里程碑式的版本,Sun 公司在这个版本中将 Java 技术体系拆分为三个方向,分别是面向桌面应用开发的 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 等。

    在这个版本中第一次内置了 JIT(Just In Time,即时)编译器,大大提高了 Java 程序的执行效率。JDK 1.2 中曾并存过三个虚拟机,Classic VM、HotSpot VM 和 Exact VM,其中 Exact VM 只在 Solaris 平台出现过;后面两款虚拟机都是内置了 JIT 编译器的,而之前版本所带的 Classic VM 只能以外挂的形式使用 JIT 编译器。

    在语言和 API 层面上,添加了 strictfp 关键字,用于声明浮点运算的结果是精确的;Java 类库中添加了 Collections 框架,提供了一套标准的数据结构和算法等。

  • 1999 年 4 月 27 日,HotSpot 虚拟机诞生。HotSpot 最初是由一家名为 Longview Technologies 的公司开发的,在 1997 年被 Sun 公司收购。HotSpot 刚发布时是作为 JDK 1.2 的附加程序提供的,后来作为 JDK 1.3 及之后版本的默认虚拟机。

  • 2000 年 5 月 8 日,JDK 1.3 发布,工程代号为 Kestrel(红隼)。代表技术有:JNDI、Java Sound、JPDA 等。在这个版本中,Java 虚拟机的默认实现从 Classic VM 切换为 HotSpot VM。

  • 2002 年 2 月 13 日,JDK 1.4 发布,工程代号为 Merlin(灰背隼),标志着 Java 真正走向成熟。JDK 1.4 带来了很多新的技术特性,如 NIO、正则表达式、异常链、日志类、XML 解析器和 XSLT 转换器等。

  • 2002 年前后还发生了一件与 Java 没有直接关系,但事实上对 Java 的发展进程影响很大的事情,就是微软公司推出了 .NET Framework,这是一个全新的软件开发平台。无论是技术实现还是目标用户都与 Java 有很多相近之处。两者的讨论、比较和竞争一直持续到今天。

  • 2004 年 9 月 30 日,JDK 5 发布,工程代号 Tiger(老虎),从这个版本开始放弃了以往“JDK 1.x”的命名方式,改为“JDK x”方式。

    自 JDK 1.2 以来,Java 在语法层面变动一直很小,但在 JDK 5 中,对 Java 语法易用性上做出了非常大的改进。如:自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环(foreach 循环)等。

    在虚拟机和 API 层面上,这个版本改进了 Java 内存模型(Java Memory Model,JMM)、提供了 java.util.concurrent 并发包等。

  • 2006 年 11 月 13 日的 JavaOne 大会上,Sun 公司计划将 Java 开源。在最后一年多的时间里,,陆续地将 JDK 各个部分在 GPL v2(GNU General Public Licence v2)协议下公开源码,并建立 OpenJDK 组织对这些源码进行管理。

  • 2006 年 12 月 11 日,JDK 6 发布,工程代号为 Mustang(野马)。在这个版本中,Sun 公司取消了从 JDK 1.2 开始长达八年之久的 J2EE、J2SE、J2ME 的产品线命名方式,启用 Java EE 6、Java SE 6、Java ME 6 的新命名方式。

    JDK 6 的改进有:提供初步的动态语言支持(通过内置 Mozilla JavaScript Rhino 引擎实现)、提供编译期注解处理器和微型 HTTP 服务器 API等。同时这个版本对 Java 虚拟机内部做了大量的改进,包括锁与同步、垃圾收集、类加载等方面。

    JDK 6 发布后,由于代码复杂性增加、Java 开源、开发 JavaFX、世界经济危机及 Oracle 对 Sun 公司的收购案等原因,Sun 公司在发展 Java 意外的事情上耗费了太多精力和资源,JDK 的更新没能维持两年发布一个主版本的研发目标。

  • 2009 年 2 月 19 日,JDK 7 完成第一个里程碑版本,工程代号为 Dolphin(海豚)。JDK 7 一共设置了十个里程碑版本,最后一个里程碑版本原计划于 2010 年 9 月 9 日结束,但由于各种原因无法按照计划完成。

    从 JDK 7 的功能清单来看,包含了许多 Java 业界期待已久的新特性,包括:

    • Lambda 项目:支持 Lambda 表达式,支持函数式编程。
    • Jigsaw 项目:虚拟机层面模块化支持。
    • 动态语言支持:Java 是静态语言,为其他运行在 Java 虚拟机上的动态语言提供支持。
    • Garbage-First 收集器。
    • Coin 项目:Java 语法细节进化。

    但令人惋惜的是,在 JDK 7 研发期间,Sun 公司陷入了技术竞争和商业竞争中,股票市值暴跌,无力推动 JDK 7 的研发工作按计划进行。

  • 2009 年 4 月 20 日,Oracle(甲骨文)宣布以一项震撼业界的现金交易,以 74 亿美元的价格成功收购了曾经市值超过 2000 亿美元的 Sun Microsystems。 Java 商标正式划归 Oracle 所有(Java 语言本身并不属于哪家公司所有,它由 JCP 组织进行管理,尽管在 JCP 中 Sun 和 Oracle 的话语权很大)。

    为了尽快结束 JDK 7 长期跳票的问题,Oracle 公司在收购 Sun 公司后,迅速启动了“B 计划”,将 Lambda 项目、Jigsaw 项目和 Coin 项目等原计划在 JDK 7 中实现的功能移至 JDK 8 中实现,同时 JDK 7 仅保留一些小的改进,以尽快发布 JDK 7。

    最终,JDK 7 包含的改进有:

    • 提供新的 G1 收集器(G1 在发布时依然处于试验阶段,直至 2012 年 4 月的 Update 4 中才正式商用)。
    • 加强对非 Java 语言的调用支持(支持 JSR-292,这项特性在 JDK 11 中还有改动)。
    • 可并行的类加载架构。

    从 JDK 7 Update 4 开始,Java SE 的核心功能正式开始为 MacOS X 操作系统提供支持,并在 JDK 7 Update 6 中完全兼容并对 ARM 指令集架构提供支持。至此,官方提供的 JDK 可以运行的操作系统包括 Windows(不包含 Windows 9.x)、Linux、Solaris 和 MacOS X。支持 ARM、x86、x86-64 和 SPARC 指令集架构。

  • 原定于 2013 年 9 月发布的 JDK 8 最终跳票到 2014 年 3 月 18 日。从 JDK 8 开始 Oracle 启用 JEP(JDK Enhancement Proposal)来定义和管理纳入新版 JDK 发布范围的功能特性。

    JDK 8 的主要特性有:

    • JEP 126:对 Lambda 表达式的支持,这让 Java 语言拥有了流畅的函数式表达能力。
    • JEP 104:内置 Nashorn JavaScript 引擎支持,用于替代 Rhino。
    • JEP 150:对 Java 类库的增强,包括新的日期时间 API、新的并发包、新的 JavaScript 引擎等。
    • JEP 122:彻底移除 HotSpot VM 中的永久代(PermGen)区域。

    在 JDK 7 中的“B 计划”中原本说好的 Jigsaw 模块化功能会在 JDK 8 中实现,但 Jigsaw 功能最终被推迟到了 JDK 9 中实现。

  • 原本计划 JDK 9 在 2016 年发布,但还是经过两次跳票,在 2017 年 9 月 21 日艰难面世。

    后面两次跳票的原因是以 IBM 和 RedHat 为首的十三家企业在 JCP 执行委员会上联手否决了 Oracle 提出的 Jigsaw 作为 Java 模块化规范进入 JDK 9 发布范围的提案。

    除了 Jigsaw 外,JDK 9 还增强了若干工具(JS Shell、JLink、JHSDB 等),整顿了 HotSpot 各个模块中各自为战的日志系统,支持 HTTP 2 客户端 API 等 91 个 JEP。

    在 JDK 9 版本发布之后,为了避免众多功能特性被集中捆绑到一个 JDK 版本上而引发交付风险等其他问题,Oracle 公司决定从此之后每六个 JDK 大版本中才会被划出一个长期支持(Long Term Support,LTS)版本。

  • 2018 年 3 月 20 日,JDK 10 发布。这个版本只包含 12 个 JEP,主要研发目标是内部重构。

    尽管 JDK 10 的改进有限,但 2018 年 Java 圈丝毫不缺乏谈资,相继发生了几件与“金钱”有关的历史大事件。

  • 2018 年 3 月 27 日,Android 的 Java 侵权案有了最终的判决,法庭裁定 Google 赔偿 Oracle 合计 88 亿美元。 要知道 2009 年 Oracle 收购 Sun 也就只花了 74 亿美元,收购完成后随机就用 Sun 的专利把 Google 告上了法庭,经过 Oracle 法务部的几轮神操作,一场官司赔偿让收购 Sun 公司等同于免费。

    想当年 Android 刚起步时,是 Sun 公司向 Google 抛去的橄榄枝,Android 的流行也巩固了 Java “第一编程语言”的行业地位。

  • 2018 年 3 月,Oracle 正式宣告 Java EE 成为历史名词,所有权直接赠送给 Eclipse 基金会,唯一的条件是以后不能使用“Java”这个商标,所以取而代之的是 Jakarta EE。 虽然 Java SE、Java EE 和 Java ME 三条产品线里确实只有 Java SE 称得上成功,但 Java EE 毕竟无比辉煌过,现在其中还持有着 JDBC、JMS、Servlet 等使用极为广泛的基础组件。

  • 2018 年 10 月,最后一届 JavaOne 大会在旧金山举行。此外还有 Java Mission Control 的开发团队也在 2018 年 6 月被解散。

  • 2018 年 9 月 15 日,JDK 11 发布。这是一个 LTS 版本的 JDK,包含 17 个 JEP,其中有 ZGC 这样革命性的垃圾收集器出现,也有把 JDK 10 中的类型推断加入 Lambda 语法这种可见的改进,但都比不过它发布时爆出来的谣言轰动:“Java 要开始收费啦!”。

    事实上,Oracle 公司在 2017 年 9 月宣布,从 JDK 11 开始,Oracle JDK 和 OpenJDK 将保持一致,Oracle JDK 将不再是免费的商业产品,而是一个免费的开发工具包,而 Oracle 公司将提供商业支持服务。 但 OpenJDK 仍然是一个免费的开源 JDK,Oracle 公司将继续参与 OpenJDK 的开发,但不再提供免费的商业支持服务。

  • 2019 年 3 月 20 日,JDK 12 发布,只包含 8 个 JEP,其中主要有 Switch 表达式、Java 微测试套件(JMH)等新功能,最引人注目的是加入了由 RedHat 领导开发的 Shenandoah 垃圾收集器。

    Shenandoah 垃圾收集器的目标与 Oracle 在 JDK 11 中发布的 ZGC 几乎完全一致,两者天生存在竞争。于是 Oracle 在 OracleJDK 12 中通过条件编译的形式将 Shenandoah 收集器的代码移除。

Java 虚拟机家族

Java 虚拟机(JVM)家族多年来经历了百家争鸣的局面,各种实现形式满足了不同的应用场景和需求。

Sun Classic/Exact VM

Sun Classic VM

  • Sun Microsystems 开发的最早期 JVM 实现,用于 Java 1.0。
  • 特点:
    • 解释器为主,性能较低。
    • 没有即时编译(JIT)技术。
    • 基于栈的架构,简单易实现。

Sun Exact VM

  • 针对嵌入式系统开发的 JVM。
  • 特点:
    • 支持精准垃圾回收(Exact Garbage Collection)。
    • 主要优化内存占用和响应速度。
    • 偏向小型设备的性能优化。

HotSpot VM

  • 背景:Sun Microsystems 于 1999 年收购 Longview Technologies 后发布。如今,HotSpot VM 是 Java 标准的官方实现。
  • 特点:
    • JIT 编译器:包括 Client 模式和 Server 模式。
      • Client 模式:针对 GUI 应用优化,启动速度快。
      • Server 模式:针对高性能服务器优化,运行性能佳。
    • 垃圾回收:支持多种垃圾回收器(Serial、Parallel、CMS、G1 等),涵盖不同需求。
    • 自适应优化:利用运行时信息,动态优化代码执行。
    • 现代 JVM 的基石:HotSpot 是 OpenJDK 的 JVM 实现,广泛用于生产环境。

Mobile/Embedded VM

  • Sun Microsystems 针对嵌入式设备(如手机、机顶盒)开发的 JVM 系列。
  • 特性:
    • 精简内存占用(适用于资源受限的设备)。
    • 高度可定制化。
    • 主要面向 Java ME(Micro Edition)应用,如 CLDC(连接设备配置)和 MIDP(移动信息设备配置)。

BEA JRockit

  • 背景:BEA Systems 开发,后被 Oracle 收购。
  • 特点:
    • 针对服务器应用进行优化。
    • 专注于低延迟和高吞吐量。
    • 独有的 Mission Control 工具提供强大的性能监控和调试功能。
    • 实现了无暂停垃圾回收(Garbage-Free Pause)。

IBM J9 VM

  • 背景:由 IBM 开发,现为 OpenJ9,已开源。
  • 特点:
    • 优化跨平台兼容性。
    • 对多种架构(x86、Power、z/OS)均进行了性能调整。
    • 提供模块化设计,可移植性强。
    • 高效垃圾回收器,例如 Balanced GC、Generational GC。

BEA Liquid VM

  • 背景:BEA Systems 开发的云原生 JVM,后被 Oracle 收购。
  • 特点:
    • 专为虚拟化和云计算优化。
    • 无需操作系统,直接运行在虚拟机管理程序(如 VMware ESX)上。
    • 被称为“Java 虚拟机的虚拟机”,用于降低虚拟化层的开销。

Azul VM

  • 背景:由 Azul Systems 开发,专注于低延迟 JVM。
  • 特点:
    • 面向大型企业应用,如金融系统。
    • 提供 Zing JVM,实现低延迟垃圾回收。
    • C4 垃圾回收器:支持大内存(TB 级别),实现无停顿垃圾回收。

Apache Harmony

  • 背景:Apache 基金会开发的开源 Java 实现,目标是提供一个替代标准的 Java 平台。
  • 特点:
    • 模块化设计,易于扩展。
    • 曾被 Google Android 的 Dalvik VM 采用部分代码。

Google Android Dalvik VM

  • 背景:为 Android 平台开发的虚拟机,兼容 Java,但运行的是自定义的 .dex 文件格式。
  • 特点:
    • 针对移动设备优化。
    • 基于寄存器架构(与传统 JVM 的栈架构不同)。
    • 支持多实例虚拟机同时运行。

ART(Android Runtime)

  • 背景:Android 后续开发的新运行时环境,替代 Dalvik。
  • 特点:
    • 提供 Ahead-of-Time (AOT) 编译。
    • 更高的性能和能效。

Microsoft JVM

  • 背景:微软早期为支持 Java 开发的 JVM,随 Internet Explorer 一起分发。
  • 特点:
    • 兼容性争议:被指控为故意破坏 Java 的跨平台性。
    • 与 Sun 的法律纠纷最终导致 Microsoft JVM 的停用。

其他 JVM

  • GCJ(GNU Compiler for Java):
    • GNU 项目的一部分,基于静态编译器生成本地代码。
  • Excelsior JET:
    • 一个商业 JVM,提供 AOT 编译器。
    • 支持打包和优化 Java 应用为独立的本地可执行文件。

展望 Java 技术的未来

无语言倾向

2018 年 4 月,Oracle Labs 的语言团队发布了一个名为 Graal VM 的项目,这是一个在 HotSpot 虚拟机基础上增强而成的跨语言全栈虚拟机,支持多种语言(Java、JavaScript、Ruby、Python、R、LLVM 等)。

Graal VM 可以无额外开销地混合使用这些语言,支持不同语言混用对方的接口和对象,也能够支持这些语言使用已经编写好的本地库文件。

24121501.png

图 Graal VM

Graal VM 的基本工作原理是将不同语言的源代码编译成中间格式(例如 LLVM 字节码)通过解释器转换为能被 Graal VM 接受的中间表示(Intermediate Representation,IR)。 譬如设计一个解释器专门对 LLVM 输出的字节码进行转换来支持 C 和 C++ 语言,这个过程称为程序特化(Specialized,也被称为 Partial Evaluation)。 Graal VM 提供了 Truffle 工具集来快速构建面向一种新语言的解释器,并用它构建了一个称为 Sulong 的高性能 LLVM 字节码解释器。

从更严格的角度上讲,Graal VM 才是真正意义上与物理计算机相对应的高级语言虚拟机,因为它与物理硬件的指令集一样,做到了只与机器特性相关而不与某种高级语言特征相关。 对于一些本来就不以速度见长的语言运行环境,由于 Graal VM 本身能够对输入的中间表示自动进行优化,在运行时还能进行及时编译优化,因此使用 Graal VM 实现往往能够获得比原生编译器更优秀的执行效率。 譬如 Graal.js 要优于 Node.js,Graal.Python 要优于 CPython,TruffleRuby 要优于 Ruby MRI 等。

对 Java 而言,Graal VM 本来就是在 HotSpot 基础上诞生的,天生就可作为一套完整的符合 Java SE 8 标准的 Java 虚拟机来使用。它和标准的 HotSpot 的差异主要在即时编译器上,其执行效率、编译质量目前与标准版的 HotSpot 相比也是互有胜负。

新一代即时编译器

对于需要长时间运行的应用来说,由于经过充分预热,热点代码会被 HotSpot 虚拟机的探测机制定位捕获,并将其编译为物理硬件可以直接执行的机器码。由此可见,运行效率很大程度上取决于即时编译器所输出的代码质量。

HotSpot 虚拟机有两个即时编译器,分别是编译耗时短但输出代码优化程度低的客户端编译器(简称为 C1)以及编译耗时长但输出代码优化质量高的服务端编译器(简称为 C2),它们在分层编译机制下与解释器相互配合共同构成 HotSpot 虚拟机的执行子系统。

自 JDK 10 起,HotSpot 中又加入了一个全新的即时编译器:Graal 编译器。Graal 编译器是以 C2 编译器的替代者身份登场的。

Graal 编译器使用与 C2 编译器一致的中间表示形式,如 Sea-of-Nodes、Ideal Graph(理想图)等。理想图是一种有向图,其节点表示程序中的元素(如变量、操作符、方法、字段等),边表示数据流(虚线)或控制流(实线)。

在代码优化方面,Graal 编译器会进行多种优化以提高执行效率,如循环向量化、垃圾收集优化等。这些优化可以显著提高编译吞吐量和内存占用,从而提升程序的性能。

Graal 编译器功能强大、性能卓越,具有广泛的应用前景和显著的优势。

编程洪同学服务平台是一个广泛收集编程相关内容和资源,旨在满足编程爱好者和专业开发人员的需求的网站。无论您是初学者还是经验丰富的开发者,都可以在这里找到有用的信息和资料,我们将助您提升编程技能和知识。
专业开发
高端定制
售后无忧
站内资源均为本站制作或收集于互联网等平台,如有侵权,请第一时间联系本站,敬请谅解!本站资源仅限于学习与参考,严禁用于各种非法活动,否则后果自行负责,本站概不承担!