JVM 运行时数据区域(Runtime Data Area)是 Java 虚拟机在执行 Java 程序过程中所管理的内存区域。需要注意的是,它与 Java 内存模型(Java Memory Model, JMM)是完全不同的概念。JVM 运行时数据区域主要由以下五部分组成:

1. 程序计数器(线程私有)
程序计数器(Program Counter Register)是一块较小的内存空间,可看作当前线程所执行字节码的行号指示器。如果当前线程正在执行 Java 方法,该计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行 Native 方法,则计数器值为 undefined。程序计数器是 JVM 规范中唯一没有规定任何 OutOfMemoryError 情况的区域。
JVM 通过线程轮流切换来获取 CPU 执行时间。为保证线程切换后能恢复到正确的执行位置,每个线程都需要一个独立的程序计数器,且各线程间互不干扰,因此它是线程私有的。
以下通过一段简单代码及其字节码指令说明其作用:
public class PcDemo {
public static int add(int a, int b) {
return a + b;
}
}
对应的字节码指令大致如下:
0: iload_0 // 从局部变量表加载变量 a 到操作数栈
1: iload_1 // 从局部变量表加载变量 b 到操作数栈
2: iadd // 两数相加
3: ireturn // 返回结果
执行过程:
- 初始状态:方法开始执行时,PC 计数器设为
0,指向第一条指令0: iload_0。 - 执行第一条指令:执行
iload_0,将局部变量表索引为 0 的整数(参数a)压入操作数栈。PC 更新为1。 - 执行第二条指令:执行
iload_1,将索引为 1 的整数(参数b)压入操作数栈。PC 更新为2。 - 执行第三条指令:执行
iadd,弹出栈顶两个整数相加,结果压回栈顶。PC 更新为3。 - 执行最后一条指令:执行
ireturn,弹出栈顶结果并返回。方法执行完毕。
若发生线程切换,各线程的 PC 值独立保存:
线程 A: PC = 2 // 下一条执行 iadd
线程 B: PC = 4 // 下一条执行 ireturn
2. Java 虚拟机栈(线程私有)
Java 虚拟机栈(JVM Stack)是线程私有的运行时数据区,生命周期与线程相同。它用于描述 Java 方法执行的内存模型:方法调用时,JVM 会创建一个**栈帧(Stack Frame)**并压入虚拟机栈;方法执行结束时,对应栈帧弹出。通常所说的'栈内存'即指此区域。



