JVM 是怎么执行Java程序的

JVM 是怎么执行Java程序的

假设我们有一个简单的 Java 方法,用来计算两个整数的和:

java 复制代码
public int add(int a, int b) {
    return a + b;
}

我们将从编写 Java 代码开始,一直到它在 JVM 中执行,详细说明每一步的流转过程。

1. 编写和编译 Java 代码

首先,我们编写 Java 代码并保存为 Add.java 文件。然后,我们使用 javac 编译器将其编译为字节码:

sh 复制代码
javac Add.java

这会生成一个 Add.class 文件,其中包含 Java 字节码。

2. 加载字节码到 JVM

当我们运行这个类时,JVM 会进行以下步骤:

复制代码
java Add

3. 类加载器(Class Loader)

JVM 的类加载器会读取 Add.class 文件并加载类定义到内存中。这包括加载方法字节码。

4. 方法区

加载的类和方法字节码存储在 JVM 的方法区中。add 方法的字节码如下所示(假设 Add.class 是如下结构):

复制代码
public int add(int a, int b);
  Code:
   0: iload_1
   1: iload_2
   2: iadd
   3: ireturn

5. 执行引擎

解释执行

JVM 的执行引擎开始逐条解释字节码并执行:

  • PC寄存器:每个线程有一个独立的 PC 寄存器,指向当前执行的字节码指令。
  • 操作数栈:用于存放操作数和中间结果。
  • 局部变量表:用于存放方法参数和局部变量。

假设我们调用 add(2, 3),执行过程如下:

字节码指令流转
  1. 指令 0: iload_1
    • 将第一个参数 a(值为 2)加载到操作数栈。
    • 操作数栈:2
  2. 指令 1: iload_2
    • 将第二个参数 b(值为 3)加载到操作数栈。
    • 操作数栈:2, 3
  3. 指令 2: iadd
    • 弹出操作数栈顶的两个值 23,执行加法操作,结果为 5,然后将结果压回操作数栈。
    • 操作数栈:5
  4. 指令 3: ireturn
    • 从操作数栈顶弹出值 5,作为方法返回值。
局部变量表

在调用 add 方法时,局部变量表内容如下:

  • 局部变量表:this, 2, 3
    • this:当前对象引用(如果方法是实例方法)。
    • 2:参数 a 的值。
    • 3:参数 b 的值。

6. 执行引擎细节

PC 寄存器

每次执行字节码指令时,PC 寄存器指向当前指令的位置:

  • 初始时:PC = 0
  • 执行 iload_1 后:PC = 1
  • 执行 iload_2 后:PC = 2
  • 执行 iadd 后:PC = 3
  • 执行 ireturn 后:方法结束,返回调用者

7. JIT 编译器

如果 add 方法被频繁调用,JVM 的 JIT 编译器会将字节码编译为本地机器码,以提高执行效率。编译后的机器码直接由 CPU 执行,不再通过解释器逐条解释字节码。

8. 调用者

方法返回值 5 被传递回调用者,调用者继续执行后续代码。

流程图示

复制代码
Java代码 -> 编译器(javac) -> 字节码(Add.class) -> JVM
 -> 类加载器 -> 方法区 -> 执行引擎
  -> [PC寄存器, 操作数栈, 局部变量表]
   -> 逐条执行字节码(解释器)
    -> JIT编译(可选)
     -> 本地机器码执行(提高性能)

总结

  • 类加载器:加载字节码到内存中。
  • 方法区:存储加载的类和方法字节码。
  • 执行引擎:解释执行字节码或将其编译为本地机器码。
  • PC寄存器:指向当前执行的字节码指令。
  • 操作数栈:存放操作数和中间结果。
  • 局部变量表:存放方法参数和局部变量。

通过上述详细解释,我们理解了 JVM 中指令流转的全过程。这一过程展示了 CPU、执行引擎、PC 寄存器、操作栈以及机器指令之间的关系。

相关推荐
linweidong4 小时前
中科闻歌Java面试题及参考答案
java·python·大模型·提示词·ai agent·mcp·rag原理
OpenAnolis小助手4 小时前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·阿里云·操作系统控制台·sysom
小玮看世界4 小时前
[Python]OD算法在OD实际运用转化参考清单
开发语言·python·算法
ForteScarlet4 小时前
Kotlin 2.4.20 现已发布,新特性多不多?
android·java·开发语言·开源·kotlin·jetbrains
萧瑟余晖4 小时前
Java深入解析篇六十二之安全机制详解
java·开发语言
小刘在重生~5 小时前
Java 常用类|包装类 装箱拆箱、Integer 缓存面试题
java·python·缓存
Orange_sparkle5 小时前
Pi Agent vs LangGraph:从人机交互、企业 RAG 到持久化工作流的完整选型指南
java·网络·人机交互
菜鸟~noob2335 小时前
【电子战】 第01篇:噪声、门限与虚警/检测概率(PFA/PD)【含matlab代码】
开发语言·matlab
奇牙coding1235 小时前
GPT-6-Astra API 接入教程:OpenRouter 路由配置 + Python/curl 示例 + 静默降级踩坑
开发语言·python·gpt·ai
lzx_0026 小时前
C++11(一)
开发语言·c++·算法