jvm虚拟机的组成部分

Java 虚拟机 (JVM) 是一个复杂的软件系统,其内部结构可以划分为几个关键的功能模块。根据功能和责任的不同,主要可以分为以下几大部分:

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

  • 职责: 负责将 .class 文件(包含字节码)加载到 JVM 中,并进行链接(验证、准备、解析)和初始化。

  • 关键组件:

    • 加载 (Loading): 查找并加载类的二进制字节码(通常来自文件系统、网络或其他来源)。由类加载器 (ClassLoader) 实现(如 BootstrapExtensionApplication/SystemCustom 加载器),遵循"双亲委派模型"。

    • 链接 (Linking):

      • 验证 (Verification): 确保被加载的 .class 文件符合 JVM 规范且不会危害 JVM 自身安全(如文件格式、字节码语义、符号引用等)。
      • 准备 (Preparation): 为类的静态变量 分配内存(在方法区)并赋予数据类型的默认初始值
      • 解析 (Resolution): 将常量池中的符号引用(名称描述)解析为直接引用(内存地址/偏移量)。
    • 初始化 (Initialization): 执行类的 clinit() 方法(编译器自动收集类中所有静态变量赋值动作和静态语句块 static{} 合并生成),为静态变量赋予程序中指定的初始值

2.运行时数据区 (Runtime Data Areas / Memory Areas)

  • 职责: JVM 在执行程序时分配和管理内存的区域。这是存储程序运行所需数据的核心区域。

  • 关键组件:

    • 方法区 (Method Area / Metaspace in HotSpot): 存储已被加载的类信息常量 (Runtime Constant Pool)静态变量 (static variables)即时编译器编译后的代码等。是线程共享的区域。

    • 堆 (Heap Area): 用于存放程序运行过程中创建的所有对象实例数组。也是垃圾回收器管理的主要区域。同样是线程共享的区域。

    • Java 虚拟机栈 (Java Virtual Machine Stacks):线程私有。每个线程在创建时都会分配一个对应的栈。栈中存储的是栈帧 (Stack Frame)。每个方法被调用时,会创建一个栈帧,栈帧中存储:

      • 局部变量表 (Local Variable Array/Local Variables): 存储基本数据类型变量、对象引用 (reference)、returnAddress 类型。
      • 操作数栈 (Operand Stack): 方法执行过程中计算的中间结果和工作空间。
      • 动态链接 (Dynamic Linking): 指向运行时常量池中该栈帧所属方法的引用。
      • 方法返回地址 (Return Address): 方法正常退出或异常终止时,需要返回到调用者的位置。
    • 本地方法栈 (Native Method Stacks): 线程私有 。服务于 JVM 调用的 native 方法(非 Java 编写,通常用 C/C++ 实现)。

    • 程序计数器 (Program Counter Register): 线程私有 。指向当前线程正在执行的字节码指令的地址(如果正在执行的是 native 方法,则为 undefined)。用于实现线程切换后能恢复到正确的执行位置。是 JVM 规范中唯一 不会发生 OutOfMemoryError 的区域。

3.执行引擎 (Execution Engine)

  • 职责: 负责解释执行 字节码指令或编译执行本地机器码指令。是程序实际运行的"CPU"。

  • 关键组件/工作方式:

    • 解释器 (Interpreter): 逐条读取、解释并执行字节码指令。启动速度快(无需编译等待),但执行速度相对较慢。
    • 即时编译器 (Just-In-Time Compiler - JIT Compiler): (例如 HotSpot JVM 中的 C1、C2、Graal)将"热点代码"(频繁执行的代码段)即时编译成本地机器码(存储在方法区),然后直接执行本地机器码,大幅提高执行效率。JIT 是 JVM 性能优化的核心。解释器和 JIT 通常会配合工作(解释器启动,JIT 在运行时介入)。
    • 垃圾回收器 (Garbage Collector - GC): 严格来说,GC 是执行引擎的核心组成部分之一(并且是一个极其重要的模块),运行在专门的 GC 线程上。 它负责自动管理堆内存中对象的分配回收,识别并清除不再被引用的对象(垃圾),释放内存空间供后续分配使用。不同的 GC 算法(如 Mark-Sweep, Mark-Compact, Copying, Generational)和收集器(如 Serial, Parallel, CMS, G1, ZGC, Shenandoah)有不同的特点和适用场景。GC 的性能对应用影响巨大。
  • 本地方法接口 (Java Native Interface - JNI)

    • 职责: 提供一套标准接口,使得在 JVM 内部运行的 Java 代码可以调用**外部的本地库(C/C++, Fortran 等语言编写)**中的方法,或者允许本地库调用 Java 代码。它充当了 Java 世界与非 Java 本地代码世界的桥梁。
    • 作用: 用于访问操作系统或硬件的底层功能(超越 Java API 的能力)、集成遗留系统代码、提高关键部分的性能等。
  • 本地方法库 (Native Method Libraries)

    • 职责: 包含通过 JNI 调用的实际本地库(例如 .dll, .so, .dylib 文件)。这些库不是 JVM 规范的一部分,但它们是被 JNI 使用的执行基础。

理解这些组成部分及其交互,是深入掌握 Java 程序运行原理、进行性能调优(特别是内存管理和 GC 调优)和问题诊断的基础。

总结图:

sql 复制代码
┌──────────────────────────────────────────────────┐
│                Java Virtual Machine              │
├────────────────┬────────────────┬────────────────┤
│  Class Loader  │ Runtime Data    │  Execution     │
│  Subsystem     │ Areas           │  Engine        │
│ ┌───────────┐  │ ┌────────────┐ │ ┌────────────┐ │
│ │  Loading  │  │ │ Method Area│ │ │ Interpreter│ │
│ └───────────┘  │ ├────────────┤ │ └────────────┘ │
│ ┌───────────┐  │ │   Heap     │ │ ┌────────────┐ │
│ │ Linking:  ├──┼─┤ (Objects)  │←┼─┤ JIT        │ │
│ │ Verify    │  │ ├────────────┤ │ │ Compiler   │ │
│ │ Prepare   │  │ │ Java Stack │ │ └────────────┘ │
│ │ Resolve   │  │ ├────────────┤ │ ┌────────────┐ │
│ └───────────┘  │ │ Native Mtd│ │ │ Garbage    ├─┘
│ ┌───────────┐  │ │ Stack      │ │ │ Collector  │ GC
│ │Initialize │  │ ├────────────┤ │ └────────────┘ Threads
│ └───────────┘  │ │ PC Registers│ │
└────────────────┴─┴────────────┴─┴────────────────┘
        ↑              ↑  ↑  ↑              ↑
        ↓              │  │  │              ↓
┌───────┴───────┐      │  │  │      ┌───────┴───────┐
│ .class Files  │      │  │  │      │ Native Method │
│ (Bytecode)    │      │  │  │      │ Libraries     │
└───────────────┘      │  │  │      └───────┬───────┘
                       │  │  │              │
                  ┌────┘  └──┼───Java Native│Interface(JNI)──┐
                  │ Thread 1 │              │                │
                  │ Thread 2 │              │                │
                  │ ...      │              │                │
                  └──────────┘              └────────────────┘
相关推荐
最后的自由10 小时前
hashcode方法导致的优化失效
jvm
最后的自由11 小时前
G1的Region的内部结构
jvm
最后的自由11 小时前
Mark Word 位分配与年龄位压缩的真相
jvm
最后的自由11 小时前
Region 大小和数量
jvm
最后的自由13 小时前
java对象的内存布局
jvm
最后的自由13 小时前
jvm 对象空间分配机制深度解析:指针碰撞 vs 空闲链表
jvm
LZQqqqqo13 小时前
C# 析构函数
jvm
乘风破浪~~14 小时前
JVM对象创建与内存分配机制
jvm
℡余晖^14 小时前
每日面试题11:JVM
jvm