Skip to content

JVM的内存模型

JVM 的内存模型(运行时数据区)是 JVM 执行 Java 程序时划分的内存区域,用于存储程序运行所需的数据。它由 线程共享区域(堆、方法区)和 线程私有区域(虚拟机栈、本地方法栈、程序计数器)组成,遵循 JSR-133 规范,确保内存管理和线程安全。


1. JVM 内存模型详解

(1) 堆(Heap)

  • 作用:存储对象实例和数组,是 GC(垃圾回收)的核心区域。
  • 特点
  • 线程共享,所有线程访问。
  • 动态分配,JVM 启动时指定大小(如 -Xms-Xmx)。
  • 分区(HotSpot JVM):
  • 新生代:Eden、Survivor(From、To),存放新对象。
  • 老年代:存放长期存活对象。
  • 示例
Object obj = new Object(); // 分配在堆上

(2) 方法区(Method Area)

  • 作用:存储类信息、常量、静态变量和 JIT 编译后的代码。
  • 特点
  • 线程共享。
  • JDK 7 前称“永久代”(PermGen),JDK 8 改为元空间(Metaspace),使用本地内存。
  • 运行时常量池
  • 存储字面量和符号引用(如 String s = "abc""abc")。
  • 示例
static int x = 10; // 存储在方法区

(3) 虚拟机栈(Java Virtual Machine Stack)

  • 作用:线程私有,存储方法执行的栈帧(Stack Frame)。
  • 栈帧内容
  • 局部变量表、操作数栈、动态链接、返回地址。
  • 特点
  • 每个线程一个栈,方法调用时压栈,结束时出栈。
  • 大小可调(如 -Xss)。
  • 异常
  • StackOverflowError:栈溢出。
  • 示例
void method() { int a = 1; } // a 在栈中

(4) 本地方法栈(Native Method Stack)

  • 作用:支持本地方法(Native Method,如 JNI 调用 C 代码)的执行。
  • 特点
  • 线程私有,与虚拟机栈类似。
  • 实现因 JVM 厂商而异。
  • 示例
System.arraycopy(); // 调用本地方法

(5) 程序计数器(Program Counter Register)

  • 作用:记录当前线程执行的字节码指令地址。
  • 特点
  • 线程私有,小块内存。
  • 指向下一条指令(字节码行号)。
  • 本地方法执行时为空。
  • 示例
  • 执行 i++ 时,PC 指向下一指令。

2. 内存模型图示

JVM 内存模型
+---------------------+
|  线程共享区域        |
|  +-------+          |
|  | 堆    |          |
|  +-------+          |
|  +-------+          |
|  | 方法区|          |
|  +-------+          |
+---------------------+
|  线程私有区域        |
|  +-------+          |
|  | 虚拟机栈 |       |
|  +-------+          |
|  +-------+          |
|  | 本地方法栈 |     |
|  +-------+          |
|  +-------+          |
|  | 程序计数器 |     |
|  +-------+          |
+---------------------+

3. 特点与作用

  • 线程共享
  • 堆:对象存储,GC 管理。
  • 方法区:类元数据,长期存在。
  • 线程私有
  • 栈:方法执行上下文,生命周期短。
  • PC:指令执行控制。
  • 内存分配
  • 动态调整(如 -Xmx 设置堆大小)。
  • 元空间默认无上限(-XX:MaxMetaspaceSize 可限)。

4. 与 Java 内存模型(JMM)的区别

  • JVM 内存模型:运行时数据区,物理划分。
  • JMM(Java Memory Model):线程间内存可见性规范,定义主内存和工作内存交互(如 volatile)。

延伸与面试角度

  • GC 影响
  • 堆分代(新生代、老年代),Minor GC 和 Full GC。
  • 内存溢出
  • 堆:OutOfMemoryError: Java heap space
  • 栈:StackOverflowError
  • 元空间:OutOfMemoryError: Metaspace
  • 调优参数
  • -Xms-Xmx:堆初始和最大。
  • -Xss:栈大小。
  • -XX:MaxMetaspaceSize:元空间上限。
  • 实际应用
  • Spring Boot:对象在堆,类信息在方法区。
  • 面试点
  • 问“结构”时,提 5 大区域。
  • 问“异常”时,提 OOM 和 SOE。

示例(内存分配)

public class Demo {
    static String s = "hello"; // 方法区
    public static void main(String[] args) {
        int x = 10; // 虚拟机栈
        Object obj = new Object(); // 堆
    }
}

总结

JVM 内存模型分为堆、方法区(共享)和栈、本地方法栈、程序计数器(私有),管理对象、类信息和线程执行。面试时,可画图或提 GC 分代,展示理解深度。