2. JVM 核心架构组成

我们可以把 JVM 看作一个运行在操作系统内部的“自动化工厂”。当你通过命令行或者各种集成开发环境(IDE)启动一个 Java 程序时,这个工厂就开始运转了。它主要由四个核心车间组成。

JVM 核心架构的四个主要组成部分

为了让存放在磁盘上的 .class 字节码文件最终变成能运行的程序,JVM 内部进行了明确的分工:

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

  • 它解决什么问题:你的 .class 文件起初只是安静地躺在计算机的硬盘里。但是,计算机的 CPU 是无法直接处理硬盘里的文件的,所有数据必须先加载到内存(RAM)中。
  • 它的工作逻辑:类加载子系统就是负责“搬运”的工人。当程序需要用到某个类时,它会去硬盘上找到对应的 .class 文件,读取里面的二进制数据,然后把这些数据按照特定的格式搬运到 JVM 的内存区域中。

2. 运行时数据区(Runtime Data Area)

  • 它解决什么问题:程序运行需要占用内存空间来存放各种数据(比如你定义的变量、创建的对象、调用的方法等)。
  • 它的工作逻辑:这就是 JVM Factory 的“内容存储仓库”,也就是我们常说的 JVM 内存。当类加载子系统把类信息搬过来后,以及程序运行过程中产生的各种临时数据,都会被分类存放在这个区域的不同位置(关于这些位置的划分,我们会在第三部分详细拆解)。

3. 执行引擎(Execution Engine)

  • 它解决什么问题:内存里现在有了“字节码指令”和“数据”,但正如第一部分所说,操作系统的 CPU 还是听不懂字节码。必须有人把这些字节码真正翻译成机器码并下达给 CPU 执行。
  • 它的工作逻辑:这是工厂的“核心生产线”。它拿到了内存里的字节码指令,通过以下两种方式进行翻译和执行:
    • 解释器(Interpreter):逐行读取字节码,读一行,翻译一行,执行一行。这种方式启动很快,但因为每次都要翻译,运行速度相对较慢。
    • 即时编译器(JIT Compiler - Just In-Time):如果有一段代码被频繁执行(比如一个执行了上万次的循环语句),执行引擎就会认为这是“热点代码”,JIT 编译器会直接把这段代码整块编译成底层的机器码并保存起来。下次再执行时,就不需要重新翻译了,速度极快。

4. 本地接口(Native Interface / JNI)

  • 它解决什么问题:Java 语言虽然强大,但有些底层操作(比如直接操作系统的文件系统、网络硬件、或者调用已经写好的 C/C++ 库)无法直接用普通的 Java 代码完成。
  • 它的工作逻辑:它充当了一座“外交桥梁”。JNI(Java Native Interface)允许 Java 代码调用底层其他语言(主要是 C 和 C++)编写的系统函数,从而赋予了 Java 操控底层的能力。

总结整个工作流程

这四个部分是如何协同工作的呢?

  1. 你写的代码被编译成 .class 文件存放在硬盘上。
  2. 类加载子系统把这个文件读入到 JVM 的运行时数据区(内存)
  3. 执行引擎开始从内存中抓取字节码。
  4. 执行引擎一边通过解释器JIT 编译器把字节码翻译成机器码交给 CPU 执行,一边在必要时通过本地接口去调用操作系统的底层功能。

了解了 JVM 整体的架构和分工之后,接下来我们将深入探讨后端开发中最核心的部分:JVM 运行时内存区域的具体划分(即堆、栈、元空间等)。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐