JVM 运行时数据区域详解
JVM 运行时数据区域(Memory Layout)是理解 Java 虚拟机底层机制的核心。它与 Java 内存模型(JMM)是两个完全不同的概念,主要包含以下五个部分:

1. 程序计数器(线程私有)
程序计数器是一块较小的内存空间,可视为当前线程执行的字节码行号指示器。如果线程正在执行 Java 方法,它记录的是当前指令的地址;若执行 Native 方法,值为 undefined。
关键点: 它是 JVM 规范中唯一没有规定任何 OOM 情况的区域。
多线程环境下,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,执行完 iload_0 后更新为 1。当发生线程切换时,A 线程的 PC 可能停留在 2(准备执行 iadd),而 B 线程的 PC 停留在 4(准备执行 ireturn),确保各自上下文独立。
2. Java 虚拟机栈(线程私有)
虚拟机栈描述的是 Java 方法执行的内存模型,生命周期与线程相同。每当方法被调用,JVM 就会创建一个栈帧(Stack Frame)并压入栈中,方法结束时弹出。

栈帧主要包含四个部分:
- 局部变量表:存储方法参数和局部变量(基本类型或对象引用)。注意,对象引用存的是堆中的地址,而非对象本身。大小在编译期确定,以 slot 形式存放。
- 操作数栈:临时存放运算数据和结果的'工作台'。字节码指令通过 push/pop 在此完成计算。


