Java-基础-05-JVM-1-综述

420 阅读8分钟

1723708345864.jpg

1 JVM 的架构

image.png

image.png

1. 类加载器子系统(Class Loader Subsystem)

类加载器负责将 .class 文件中的 Java 字节码加载到 JVM 中,并将这些类文件解析为可以被 JVM 使用的格式。类加载器按需加载类,并且具有以下几种类型:

  • 启动类加载器(Bootstrap ClassLoader) :JVM 自带的加载器,负责加载核心 Java 类库(如 rt.jar)。
  • 扩展类加载器(Extension ClassLoader) :加载扩展的类库,例如 lib/ext 目录下的 JAR 文件。
  • 应用程序类加载器(Application ClassLoader) :加载用户编写的应用程序代码(即类路径上的类和库)。

2. 运行时数据区(Runtime Data Areas) JVM 的运行时数据区负责存储 Java 程序执行过程中使用的数据。它主要由以下几个部分组成:

  • 方法区(Method Area) :存储类信息、常量、静态变量和编译后的代码。方法区是线程共享的区域。
  • 堆(Heap) :堆是 JVM 中最大的内存区域,主要用于存储对象实例。堆内存是线程共享的,所有对象和数组都存储在堆中。
  • 虚拟机栈(JVM Stack) :每个线程有自己的栈,栈中存储了局部变量、方法调用链以及返回值。每个方法调用都会在栈中创建一个栈帧,用于存储该方法的执行状态。
  • 本地方法栈(Native Method Stack) :为使用本地方法服务,如 JNI 调用。与 JVM 栈类似,但专门用于调用本地方法。
  • 程序计数器(PC Register) :每个线程有自己的程序计数器,记录线程当前执行的指令地址。如果线程正在执行 Java 方法,则该计数器记录正在执行的字节码指令的地址。

3. 执行引擎(Execution Engine)

执行引擎是 JVM 的核心,它负责将字节码翻译为机器码并执行。执行引擎主要包括以下几个部分:

  • 解释器(Interpreter) :逐行解释和执行字节码。解释器执行速度较慢,但启动迅速,适用于需要快速启动的场景。
  • 即时编译器(Just-In-Time Compiler, JIT) :JIT 编译器通过将热点代码(频繁执行的代码)编译为本地机器码,提高执行效率。JVM 的 JIT 编译器会在程序运行时动态地进行优化。
  • 垃圾收集器(Garbage Collector, GC) :负责自动管理内存,回收不再使用的对象,防止内存泄漏。JVM 支持多种垃圾收集器,如串行收集器、并行收集器和 G1 垃圾收集器。

4. 本地方法接口(Native Interface)

本地方法接口(JNI)允许 JVM 调用平台特定的本地代码(通常是 C 或 C++ 代码),这对于系统级编程或调用系统 API 非常有用。

2 Java 代码执行

image.png

2.1 JVM 的工作流程

JVM 的工作流程如下:

  1. 加载和验证类:JVM 通过类加载器将 .class 文件加载到内存中,并进行验证,确保字节码的格式和结构是正确的。
  2. 执行字节码:JVM 通过解释器或 JIT 编译器执行字节码。如果代码是热点代码,JIT 编译器会将其编译为本地机器码,以提高性能。
  3. 内存管理:JVM 负责自动内存管理和垃圾回收。垃圾收集器会周期性地检查不再使用的对象,并回收这些对象的内存。
  4. 线程调度和同步:JVM 也负责线程的创建、调度和同步管理。它为多线程提供了一个安全的执行环境

2.2 JVM 、 JRE 、 JDK 的关系

JVM只是一个翻译,把Class翻译成机器识别的代码,但是需要注意,JVM 不会自己生成代码,需要大家编写代码,同时需要很多依赖类库,这个 时候就需要用到JRE。 JRE是什么,它除了包含JVM之外,提供了很多的类库(就是我们说的jar包,它可以提供一些即插即用的功能,比如读取或者操作文件,连接网络, 使用I/O等等之类的)这些东西就是JRE提供的基础类库。JVM 标准加上实现的一大堆基础类库,就组成了Java 的运行时环境,也就是我们常说的 JRE (JavaRuntimeEnvironment)。 但对于程序员来说,JRE还不够。我写完要编译代码,还需要调试代码,还需要打包代码、有时候还需要反编译代码。所以我们会使用JDK,因为JDK还提供了一些非常好用的小工具,比如 javac(编译代码)、java、jar(打包代码)、javap(反编译<反汇编>)等。 JVM的作用是:从软件层面屏蔽不同操作系统在底层硬件和指令的不同。这个就是我们在宏观方面对JVM的一个认识。 同时 JVM 是一个虚拟化的操作系统,类似于 Linux 或者 Windows 的操作系统,只是它架在操作系统上,接收字节码也就是 class ,把字节码翻译成操作系统上的 机器码且进行执行。

3 从跨平台到跨语言

跨平台:

我们写的一个类,在不同的操作系统上(Linux、Windows、MacOS等平台)执行,效果是一样,这个就是JVM的跨平台性。为了实现跨平台型,不同操作系统有对应的JDK的版本。www.oracle.com/java/techno…

跨语言(语言无关性):

JVM只识别字节码,所以JVM其实跟语言是解耦的,也就是没有直接关联,JVM运行不是翻译Java文件,而是识别class文件,这个一般称之为字节码。还有像Groovy 、Kotlin、Scala等等语言,它们其实也是编译成字节码,所以它们也可以在JVM上面跑,这个就是JVM的跨语言特征。 Java 的跨语言性一定程度上奠定了非常强大的 java 语言生态圈。

4 Java 的发展历史

1995 年 5 月 23 日,Sun 公司正式发布了Java 语言和HotJava 浏览器; 1996 年 1 月,Sun公司发布了 Java的第一个开发工具包(JDK 1. 0 ); 1996 年 4 月, 10 个最主要的操作系统供应商申明将在其产品中嵌入 Java 技术,发展可真是迅雷不及掩耳; 1996 年 9 月,大约 8. 3 万个网页应用了Java 技术来制作,这就是早年的互联网,即 JavaApplet,真香定律; 1996 年 10 月,Sun公司发布了 Java平台第一个即时编译器(JIT),这一年很不平凡; 1997 年 2 月 18 日,JDK 1. 1 面世,在随后的三周时间里,达到了 22 万次的下载量,PHP 甘拜下风; 1999 年 6 月,Sun公司发布了第二代Java 三大版本,即 J 2 SE、J 2 ME、J 2 EE,随之Java 2 版本发布; 2000 年 5 月 8 日,JDK 1. 3 发布,四年升三版,不算过分哈; 2000 年 5 月 29 日,JDK 1. 4 发布,获得Apple 公司 MacOS的工业标准支持; 2001 年 9 月 24 日,JavaEE 1. 3 发布,注意是EE,从此开始臃肿无比; 2002 年 2 月 26 日,J 2 SE 1. 4 发布,自此 Java的计算能力有了大幅度的提升,与 J 2 SE 1. 3 相比,多了近 62 %的类与接口; 2004 年 9 月 30 日 18 : 00 PM,J 2 SE 1. 5 发布, 1. 5 正式更名为JavaSE 5. 0 ; 2005 年 6 月,在JavaOne 大会上,Sun公司发布了JavaSE 6 ; 2009 年 4 月 20 日,Oracle 宣布收购 Sun,该交易的总价值约为 74 亿美元; 2010 年 Java 编程语言的创始人 JamesGosling从 Oracle 公司辞职,一朝天子一朝臣,国外也不例外; 2011 年 7 月 28 日,Oracle 公司终于发布了 Java 7 ,这次版本升级经过了将近 5 年时间; 2014 年 3 月 18 日,Oracle 公司发布了 Java 8 ,这次版本升级为 Java 带来了全新的 Lambda表达式。

  • 2011年:Java 7 发布 Java 7 引入了一些新的语言特性和性能提升,包括:

    • try-with-resources 语法,用于简化资源管理。
    • Switch 支持字符串
    • Fork/Join 框架,用于并行编程。
  • 2014年:Java 8 发布 Java 8 是 Java 语言历史上的一个重要里程碑,带来了众多现代编程语言的特性:

    • Lambda 表达式:简化了函数式编程,使得处理集合和流操作变得更加容易。
    • Streams API:提供了一种处理集合的函数式风格,使代码更简洁。
    • 默认方法(Default Methods) :允许接口中定义方法实现。
    • 新的日期和时间 API:引入了更强大的时间和日期处理类(java.time)。
  • 2017年:Java 9 发布 Java 9 引入了 模块系统(Project Jigsaw) ,使得开发者可以将应用程序拆分成更小的模块,提升了代码的组织性和安全性。

  • 2018年:Java 的发布周期变为每 6 个月 Java 开始采用新的发布周期,每 6 个月发布一个新的主要版本。这使得新功能能够更快地进入开发者的手中,Java 语言和生态系统变得更加灵活和动态。

  • 2018年:Java 11(LTS 版本) Java 11 是一个长期支持(LTS)版本,引入了新的特性,并去除了旧的特性(如 Applet)。它标志着 Oracle 提供 LTS 版本支持的开始,企业用户可以选择稳定的长期支持版本。

  • 2021年:Java 17(LTS 版本) Java 17 是下一个 LTS 版本,继续简化语言并增强其性能。它引入了 sealed classespattern matchingrecords 等新特性。