Skip to content

JVM的内存区域有什么

JVM 内存区域

JVM 的运行时数据区分为以下几个部分: 1. 方法区(Method Area):存储类信息、常量池,线程共享。 2. 堆(Heap):存储对象实例和数组,线程共享。 3. 虚拟机栈(JVM Stack):存储方法调用的栈帧,线程私有。 4. 本地方法栈(Native Method Stack):支持本地方法调用,线程私有。 5. 程序计数器(Program Counter Register):记录当前指令地址,线程私有。

核心点

  • 线程共享:方法区、堆。
  • 线程私有:栈、本地方法栈、程序计数器。

1. 内存区域详解

(1) 方法区(Method Area)

  • 作用
  • 存储类加载后的元信息。
  • 内容
  • 类结构:字段、方法、构造器。
  • 运行时常量池:字面量、符号引用。
  • 静态变量(JDK 1.7 前)。
  • 特点
  • 线程共享。
  • JDK 1.7 前叫“永久代”(PermGen),1.8 改为元空间(Metaspace),用本地内存。
  • 异常
  • OutOfMemoryError: Metaspace:元空间溢出。

(2) 堆(Heap)

  • 作用
  • 存储所有对象实例和数组。
  • 划分
  • 年轻代(Young Generation)
    • Eden:新对象创建。
    • Survivor(S0, S1):存活对象。
  • 老年代(Old Generation):长期存活对象。
  • 特点
  • 线程共享。
  • 垃圾回收(GC)主要区域。
  • 异常
  • OutOfMemoryError: Java heap space:堆溢出。

(3) 虚拟机栈(JVM Stack)

  • 作用
  • 管理 Java 方法调用。
  • 内容
  • 栈帧(Stack Frame)
    • 局部变量表:基本类型、引用。
    • 操作数栈:计算中间结果。
    • 动态链接:解析方法引用。
    • 返回地址:方法结束后的跳转。
  • 特点
  • 线程私有,每个线程一个栈。
  • 方法调用时入栈,结束时出栈。
  • 异常
  • StackOverflowError:栈深度超限(如递归)。
  • OutOfMemoryError:栈空间不足。

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

  • 作用
  • 支持本地方法(JNI 调用,如 C/C++)。
  • 内容
  • 类似虚拟机栈,存储本地方法的栈帧。
  • 特点
  • 线程私有。
  • 实现依赖 JVM(如 HotSpot 可能与 JVM 栈合并)。
  • 异常
  • StackOverflowErrorOutOfMemoryError

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

  • 作用
  • 记录当前线程执行的字节码指令地址。
  • 内容
  • 存储下一条指令的偏移量。
  • 本地方法时可能为空。
  • 特点
  • 线程私有。
  • 唯一无溢出异常的区域。
  • 目的
  • 确保线程切换后恢复执行位置。

2. 内存区域图示

JVM 内存:
+-------------------+
| 方法区 (共享)     |
| 堆 (共享)         |
+-------------------+
| 线程 1:           |
|   程序计数器      |
|   虚拟机栈        |
|   本地方法栈      |
+-------------------+
| 线程 2: ...       |
+-------------------+

3. 内存管理与 GC

  • 线程共享区
  • 方法区:类卸载时回收(少见)。
  • 堆:GC 主要目标,分代回收(Minor GC、Major GC)。
  • 线程私有区
  • 栈:方法结束自动回收。
  • 程序计数器:线程结束释放。

HotSpot 实现

  • JDK 1.7
  • 永久代在堆中,受 -XX:MaxPermSize 限制。
  • JDK 1.8
  • 元空间移到本地内存,受 -XX:MaxMetaspaceSize 控制。
  • 字符串常量池移到堆。

4. 示例分析

class Demo {
    static int x = 10;
    int y = 20;

    void method() {
        int z = 30;
    }
}

Demo d = new Demo();
d.method();
  • 方法区:存储 Demo 的类信息、x
  • :存储 d 对象(含 y = 20)。
  • 虚拟机栈method() 的栈帧(含 z = 30)。
  • 程序计数器:指向当前指令。

5. 延伸与面试角度

  • 与对象创建
  • 堆分配对象,栈存引用。
  • GC 影响
  • 堆分代优化回收效率。
  • 实际应用
  • Spring:堆存 Bean,方法区存类。
  • 面试点
  • 问“区域”时,提五部分及共享/私有。
  • 问“变化”时,提元空间。

总结

JVM 内存区域包括方法区、堆(共享)和栈、本地方法栈、程序计数器(私有),各有分工,支撑类加载和运行。面试时,可画内存图或提 GC 影响,展示理解深度。