第一章-JVM和Java体系结构

环境

系统 : Windows 10

JDK : 1.8

前言

大部分Java开发人员,除了会在项目中使用到与Java平台相关的各种高精尖技术,对于Java技术的核心Java虚拟机了解甚少。在项目的开发过程中,可能会遇到虾米那这些问题。

  • 运行着的线上系统突然卡死,系统无法访问,甚至直接OOM!
  • 想解决线上JVM GC问题,但却无从下手。
  • 新项目上线,对各种JVM参数设置一脸茫然,只好使用默认配置。
  • 每次面试之前都要重新背一遍JVM的一些原理概念性的东西,然而面试官却经常问你在实际项目中如何调优VM参数,如何解决GC、OOM等问题,一脸懵逼。

我们为什么要学习JVM

  • 面试的需要(BATJ、TMD,PKQ等面试都爱问)
  • 中高级程序员必备技能
  • 项目管理、调优的需要
  • 追求极客的精神
    • 比如:垃圾回收算法、JIT、底层原理

Java VS C++

  1. Java的垃圾收集机制为我们打理了很多繁琐的工作,大大提高了开发的效率,但是,垃圾收集也不是万能的,懂得JVM内部的内存结构、工作机制,是设计高扩展性应用和诊断运行时问题的基础,也是Java工程师进阶的必备能力。
  2. C++语言需要程序员自己来分配内存和回收内存,对于高手来说可能更加舒服,但是对于普通开发者,如果技术实力不够,很容易造成内存泄漏。而Java全部交给JVM进行内存分配和回收,这也是一种趋势,减少程序员的工作量。

Java-vs-C++

Java官方文档

Java 语言和虚拟机规范

Open JDK和Oracle JDK

在JDK11之前,Oracle JDK中还会存在一些Open JDK中没有的,闭源的功能。但在JDK11中,我们可以认为Open JDK和Oracle JDK代码实质上已经达到完全一致的程度了。主要的区别就是两者更新周期不一样

什么是虚拟机

虚拟机概念

所谓虚拟机(Virtual Machine),就是一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。

  • 系统虚拟机
    • 大名鼎鼎的Virtual Box,VMware就属于系统虚拟机,它们完全是对物理计算机硬件的仿真(模拟),提供了一个可运行完整操作系统的软件平台。
  • 程序虚拟机
    • 程序虚拟机的典型代表就是Java虚拟机,它专门为执行单个计算机程序而设计,在Java虚拟机中执行的指令我们称为Java字节码指令。

无论是系统虚拟机还是程序虚拟机,在上面运行的软件都被限制于虚拟机提供的资源中。

Java虚拟机

  • Java虚拟机是一台执行Java字节码的虚拟计算机,它拥有独立的运行机制,其运行的Java字节码也未必由Java语言编译而成。
  • JVM平台的各种语言可以共享Java虚拟机带来的跨平台性、优秀的垃圾回器,以及可靠的即时编译器。
  • Java技术的核心就是Java虚拟机(JVM,Java Virtual Machine),因为所有的Java程序都运行在Java虚拟机内部。

作用

Java虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对应平台上的机器指令执行。每一条Java指令,Java虚拟机规范中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在哪里。

特点

  • 一次编译,到处运行
  • 自动内存管理
  • 自动垃圾回收功能

JVM的位置

JVM是运行在操作系统之上的,它与硬件没有直接的交互

JVM所处位置

jvm的位置

JVM的整体结构

从整体上看,JVM内部被划分为一下五个部分:

  1. 类加载子系统
  2. 运行时数据区
  3. 执行引擎
  4. 本地方法接口
  5. 本地方法库

image-20231125110949260

备注:

  • HotSpot VM是目前市面上高性能虚拟机的代表作之一。
  • 它采用解释器与即时编译器并存的架构。
  • 在今天,Java程序的运行性能早已脱胎换骨,已经达到了可以和C/C++程序一较高下的地步。

Java 代码执行流程

Java代码执行流程

JVM的架构模型

Java 编译器输入的指令流基木上是一种基于栈的指令集架构,另外一种指令集架构则是基于寄存器的指令集架构

架构特点

具体来说,这两种架构之间的区别:

  • 基于栈式架构的特点
    • 设计和实现更简单,适用于资源受限的系统;
    • 避开了寄存器的分配难题:使用零地址指令方式分配
    • 指令流中的指令大部分是零地址指令,其执行过程依赖于操作栈。指令集更小,编译器容易实现。
    • 不需要硬件支持,可移植性更好,更好实现跨平台
  • 基于寄存器架构的特点
    • 典型的应用是 x86 的二进制指令集:比如传统的 PC 以及 Android 的 Davlik 虚拟机。
    • 指令集架构则完全依赖硬件,可移植性差
    • 性能优秀和执行更高效
    • 花费更少的指令去完成一项操作。
    • 在大部分情况下,基于寄存器架构的指令集往往都以一地址指令、二地址指令和三地址指令为主,而基于栈式架构的指令集却是以零地址指令为主。

字节码对比

同样执行2+3这种逻辑操作,其指令分别如下:

  • 基于栈的计算流程(以Java虚拟机为例):

    iconst_2 // 常量2入栈
    istore_1
    iconst_3 // 常量3入栈
    istore_2
    iload_1
    iload_2
    iadd // 常量2/3出栈,执行相加
    istore_0 // 结果5入栈

    8个指令

  • 而基于寄存器的计算流程

    mov eax,2 // 将eax寄存器的值设为1
    add eax,3 // 使eax寄存器的值加3

    2个指令

JVM架构总结

  • 由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。栈的优点:跨平台,指令集小,编译器容易实现,缺点是性能比寄存器差一些。
  • 时至今日,尽管嵌入式平台已经不是Java程序的主流运行平台了(准确来说应该是HotSpot VM的宿主环境已经不局限于嵌入式平台了),那么为什么不将架构更换为基于寄存器的架构呢?因为基于栈的架构跨平台性好、指令集小,虽然相对于基于寄存器的架构来说,基于栈的架构编译得到的指令更多,执行性能也不如基于寄存器的架构好,但考虑到其跨平台性与移植性,我们还是选用栈的架构

JVM的生命周期

虚拟机的启动

Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。

虚拟机的执行

  • 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序
  • 程序开始执行时他才运行,程序结束时他就停止
  • 执行一个所谓的Java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程

虚拟机的退出

有如下的几种情况:

  1. 程序正常执行结束
  2. 程序在执行过程中遇到了异常或错误而异常终止
  3. 由于操作系统用现错误而导致Java虚拟机进程终止
  4. 某线程调用Runtime类或System类的exit()方法,或Runtime类的halt()方法,并且Java安全管理器也允许这次exit()或halt()操作。
  5. 除此之外,JNI(Java Native Interface)规范描述了用JNI Invocation API来加载或卸载 Java虚拟机时,Java虚拟机的退出情况。

JVM发展历程

  • Sun Classic VM

    • 早在 1996 年 Java 1.0 版本的时候, Sun 公司发布了一款名为 Sun Classic VM 的 J ava 虚拟机,它同时也是世界上第一款商用 Java 虚拟机, JDK1.4 时完全被淘汰。
    • 这款虚拟机内部只提供解释器。如果使用 JIT 编译器,就需要进行外挂。但是一旦使用了 J 编译器, J エ T 就会接管虚拟机的执行系统。解释器就不再工作。解释器和编译器不能配合工作
    • 现在 hotspot 内置了此虚拟机。
  • Exact VM

    • 为了解決上一个虚拟机问题,jdk1.2 时, sun 提供了此虚拟机。
    • Exact Memory Management :准确式内存管理
      • 也可以叫 Non-Conservative / Accurate Memory Management
      • 虚拟机可以知道内存中某个位置的数据具体是什么类型。
    • 具备现代高性能虚拟机的雏形
      • 热点探测
      • 编译器与解释器混合工作模式
    • 只在 Solaris 平台短暂使用,其他平台上还是 classic vm
    • 英雄气短,终被 Hotspot 虚拟机替换
  • SUN 公司的 Hotspot VM

    • Hotspot 历史
      • 最初由一家名为 “ Longview Technologies “ 的小公司设计
      • 1997 年,此公司被 Sun 收购; 2009 年, Sun 公司被甲骨文收购。
      • JDK 1. 3 时, Hotspot VM 成为默认虚拟机
    • 目前Hotspot 占有绝对的市场地位,称霸武林。
      • 不管是现在仍在广泛使用的 JDK 6,还是使用比例较多的 JDK 8中,默认的虛拟机都是 Hotspot
      • Sun / Oracle JDK 和 OpenJDK 的默认虚拟机
      • 因此本课程中默认介绍的虚拟机都是 Hotspot,相关机制也主要是指 Hotspot 的 GC 机制。(比如其他两个商用虚拟机都没有方法区的概念)
    • 从服务器、桌面到移动端、嵌入式都有应用。
    • 名称中的 Hotspot 指的就是它的热点代码探测技术。
      • 通过计数器找到最具编译价值代码,触发即时编译或栈上替换
      • 通过编译器与解释器协同工作,在最优化的程序响应时间与最佳执行性能中取得平衡
  • BEA 的 JRockit

    • 专注于服务器端应用
      • 它可以不太关注程序启动速度,因此 JRockit 内部不包含解析器实现,全部代码都靠即时编译器编译后执行。
    • 大量的行业基准测试显示,JRockit JVM 是世界上最快的 JVM
      • 使用 JRockit 产品,客户已经体验到了显著的性能提高(一些超过了 70%)和硬件成本的减少(达 50%)。
    • 优势:全而的 Java 运行时解决方案组合
      • JRockit 面向延迟敏感型应用的解决方案 JRockit Real Time 提供以毫秒或微秒级的 JVM 响应时间,适合财务、军事指挥、电信网络的需要
      • MissionControl 服务套件,它是一组以极低的开销来监控、管理和分析生产坏境中的应用程序的工具。
    • 2008 年, BEA 被 Oracle 收购
    • Oracle 表达了整合两大优秀虚拟机的工作,大致在 JDK8 中完成。整合的方式是在 Hotspot 的基础上,移植 JRockit的优秀特性。
    • 高斯林:目前就职于谷歌,研究人工智能和水下机器人
  • IBM 的 J9

    • 全称:IBM Technology for Java Virtual Machine ,简称 IT4J ,内部代号: J9
    • 市场定位与 Hotspot 接近,服务器端、桌而应用、嵌入式等多用途 VM
    • 广泛用于 IBM 的各种 Java 产品。
    • 目前,有影响力的三大商用虚拟机之一,也号称是世界上最快的Java虚拟机。
    • 2017 年左右,IBM 发布了开源 J9 VM ,命名为 OpenJ9,交给 Eclipse 基金会管理,也称为 Eclipse OpenJ9
  • KVM 和 CDC/CLDC Hotspot

    • Oracle 在 Java ME 产品线上的两款虛拟机为: CDC/CLDC Hotspot Implementation VM
    • KVM(Kilobyte )是 CLDC-HI 早期产品
    • 目前移动领域地位尴尬,智能平机被 Android 和 IOS 二分天下。
    • KVM 简单、轻量、高度可移植,面向更低端的设备上还维持自己的一片市场
      • 智能控制器、传感器
      • 老人手机、经济欠发达地区的功能手机
    • 所有的虛拟机的原则:一次编译,到处运行。
  • Azul VM

    • 前面三大 “高性能 Java 虚拟机” 使用在通用硬件平台上

    • 这里 Azul VM 和 BEA Liquid VM 是

      与特定硬件平台绑定、软硬件配合的专有虚拟机

      • 高性能 Java 虚拟机中的战斗机。
    • Azul VM 是 Azul Systems 公司在 Hotspot 基础上进行大量改进,运行于 Azul Systems 公司的专有硬件 Vega 系统上的 Java 虚拟机。

    • 每个 Azul VM 实例都可以管理至少数十个 CPU 和数百 GB 内存的硬件资源,并提供在巨大内存范围内实现可控的 GC 时间的垃圾收集器、专有硬件优化的线程调度等优秀特性

    • 2010 年,Azul Systems 公司开始从硬件转向软件,发布了自己的 Zing JVM ,可以在通用 x86 平台上提供接近于 Vega 系统的特性。

  • Liquid VM

    • 高性能 Java 虚拟机中的战斗机。
    • BEA 公司开发的,直接运行在自家 Hypervisor 系统上
    • Liquid VM 即是现在的 JRockit VE( Virtual Edition ), Liquid VM 不需要操作系统的支持,或者说它自己本身实现了一个专用操作系统的必要功能,如线程调度、文件系统、网络支持等。
    • 随着 JRockit 虚拟机终止开发, Liquid VM项目也停止了。
  • Apache Harmony

    • Apache 也曾经推出过与 JDK 1.5 和 JDK 1.6 兼容的 Java 运行平台 Apache Harmony
    • 它是 IBM 和 Intel 联合开发的开源 JVM ,受到同样开源的 OpenJDK 的压制,Sun 坚决不让 Harmony 获得 JCP 认证,最终于 2011 年退役, IBM 转而参与 OpenJDK
    • 虽然目前并没有 Apache Harmony 被大规模商用的案例,但是它的 Java 类库代码吸纳进了 Android SDK。
  • Microsoft JVM

    • 微软为了在工 E3 浏览器中支持 Java Applets ,开发了 Microsoft JVM 。
    • 只能在 Windows 平台下运行。但确是当时 Windows 下性能最好的 Java VM 。
    • 1997 年, Sun 以侵犯商标、不正当竞争罪名指控微软成功,赔了 Sun 很多钱。微软在 Windows SP3 中抹掉了其 VM 。现在 Windows 上安装的 JDK 都是 Hotspot
  • TaobaoJVM

    • 由 Ali JVM团队发布。阿里,国内使用 Java 最强大的公司,覆盖云计算、金融、物流电商等众多领域,需要解决高并发、高可用、分布式的复合问题。有大量的开源产品
    • 基于 OpenJDK 开发了自己的定制版本 AlibabaJDK ,简称 AJDK。是整个阿里 Java体系的基石。
    • 基于 OpenJDK Hotspot VM 发布的国内第一个优化、深度定制且开源的高性能服务器版 Java虚拟机
      • 创新的 GCIH( GC invisible heap )技术实现了 off-heap ,即将生命周期较长的 Java对象从 heap 中移到heap 之外,并且 GC 不能管理 GCIH 内部的 Java对象,以此达到降低 GC 的回收频率和提升 GC 的回收效率的目的
      • GCIH 中的对象还能够在多个 Java虚拟机进程中实现共享
      • 使用 crc32 指令实现 JVM intrinsic 降低 JNI 的调用开销 \
      • PMU hardware 的 Java profiling tool 和诊断协助功能
      • 针对大数据场景的 ZenGC
    • taobao vm 应用在阿里产品上性能高,硬件严重依赖 intel 的 cpu损失了兼容性,但提高了性能
      • 目前已经在淘宝、天猫上线,把 Oracle 官方 JVM版木全部替换了。
  • Dalvik VM

    • 谷歌开发的,应用于 Android 系统,并在 Android 2.2 中提供了 JIT ,发展迅猛。
    • Dalvik vm 只能称作虚拟机,而不能称作“Java虚拟机”,它没有遵循Java虚拟机规范
    • 不能直接执行 Java 的 Class 文件
    • 基于寄存器架构,不是 jvm 的栈架构
    • 执行的是编译以后的 dex( Dalvik Executable )文件。执行效率比较高
      • 它执行的 dek( Dalvik Executable )文件可以通过 class 文件转化而来,使用 Java 语法编写应用程序,可以直接使用大部分的 Java api 等。
    • Android 5. 0 使用支持提前编译( Ahead of Time Compilation , AOT )的 ART VM 替换 Dalvik VM 。
  • Graal VM

    • 2018 年 4 月, Oracle Labs 公开了 Graal VM,号称 “ Run Programs Faster Anywhere “,勃勃野心。
    • 与 1995 年 Java 的 “ write once, run anywhere “ 遥相呼应。
    • Graal VM 在 Hotspot VM 基础上増强而成的跨语言全栈虚拟机,可以作为 “任何语言” 的运行平台使用。语言包括: Java 、Scala 、 Groovy 、 Kotlin ; C 、 C ++、 JavaScript、 Ruby、 Python 、 R 等
    • 支持不同语言中混用对方的接口和对象,支持这些语言使用已经编写好的本地库文件
    • 工作原理是将这些语言的源代码或源代码编译后的中间格式,通过解释器转换为能被 Graal VM 接受的中间表示。Graal VM 提供 Truffle 工具集快速构建面向一种新语言的解释器。在运行时还能进行即时编译优化,获得比原生编译器更优秀的执行效率。
    • 如果说 HotSpot 有一天真的被取代,Graal VM 希望最大。但是 Java 的软件生态没有丝毫变化

总结

具体JVM的内存结构,其实取决于其实现,不同厂商的JVM,或者同一厂商发布的不同版本,都有可能存在一定差异。主要以Oracle HotSpot VM为默认虚拟机。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 george_95@126.com