JVM内存模型深度解析:四大区域的职能与底层实现

155 阅读2分钟

一、堆区(Heap):所有对象的共享仓库

堆区是 JVM 中最大的一块内存区域,所有通过 new 关键字创建的对象实例和数组都存储在此。

  • 核心特性

    • 线程共享:所有线程共享同一块堆内存。
    • GC 主战场:垃圾回收器(GC)主要在此区域工作。
    • 分代设计:为优化 GC,堆内存被划分为新生代老年代。新生代又包含 Eden 区和 Survivor 区。
  • 内存分配:对象首先在新生代的 Eden 区分配。当 Eden 区空间不足时,会触发 Minor GC。存活下来的对象会被移动到 Survivor 区,经过多次 GC 仍然存活的对象会被晋升到老年代。


二、虚拟机栈(JVM Stack):线程私有的方法执行区

虚拟机栈是一种遵循“后进先出”(LIFO)原则的线性数据结构,每个方法被调用时,都会为其创建一个栈帧(Stack Frame) ,栈帧中包含了方法执行时的所有信息。

  • 核心结构

    • 局部变量表:存储基本类型和对象引用。
    • 操作数栈:用于方法的运算。
    • 动态链接:指向方法区的方法引用。
    • 方法出口:方法执行完毕后,返回到调用者的地方。
  • 特点

    • 线程私有:每个线程都有自己独立的栈。
    • 生命周期:栈帧的生命周期与方法的执行同步。方法开始时入栈,方法结束时出栈,数据自动销毁。
    • 异常:当方法调用深度超过栈的容量时,会抛出 StackOverflowError

三、方法区(Method Area)与元空间(Metaspace):类的“档案室”

方法区是 JVM 中一个逻辑概念,用于存储已被虚拟机加载的类信息。

  • 核心数据

    • 类信息:类名、字段、方法、父类信息。
    • 运行时常量池final 常量、字符串常量。
    • 静态变量static 修饰的变量。
  • Java 8的演进:在 JDK 8 之后,方法区元空间(Metaspace)取代。Metaspace 使用的是本地内存,不再受限于 JVM 堆内存。


四、程序计数器(PC Register):线程的“任务进度条”

程序计数器是 JVM 内存中唯一不会发生 OutOfMemoryError 的区域

  • 核心作用:它存储了当前线程正在执行的字节码指令的地址。当线程切换时,PC 寄存器会保存当前线程的执行位置,以便线程恢复时能够继续执行。

  • 特点

    • 线程私有:每个线程都有一个独立的 PC 寄存器。
    • 生命周期PC 寄存器的生命周期与线程同步。