运行时数据区
约 1092 字大约 4 分钟
2025-08-28
Java 虚拟机在运行 Java 程序时将内存划分为若干个数据区域,这些区域统称为 运行时数据区(Runtime Data Area)。这些区域服务于不同的目的,且根据是否被线程共享,可分为线程私有和线程共享两类。
| 区域名称 | 类型 | 是否线程私有 | 关键作用 | 特殊说明 |
|---|---|---|---|---|
| 程序计数器 | 线程私有 | 是 | 存储当前线程执行的字节码指令地址 | 不会抛出 OutOfMemoryError |
| 虚拟机栈 | 线程私有 | 是 | 每个方法调用的内存模型 | 可能抛出 StackOverflowError |
| 本地方法栈 | 线程私有 | 是 | 调用 native 方法的内存模型 | 部分实现可能与虚拟机栈合用 |
| Java 堆 | 线程共享 | 否 | 存放对象实例 | GC 主要管理区域,逻辑分为年轻代、老年代 |
| 方法区 | 线程共享 | 否 | 存储类信息、常量、静态变量等 | JDK 1.8 使用元空间替代永久代 |
| 直接内存 | 非 JVM | 否 | 提升 I/O 操作性能 | 不属于 JVM 管理,需手动管理 |
线程私有区域
程序计数器(Program Counter Register)
- 定义:程序计数器是一块较小的内存空间,用于记录当前线程执行的字节码指令地址。
- 作用:在多线程环境中,JVM 通过程序计数器实现线程切换后的程序恢复。
- 特点:
- 每个线程有独立的程序计数器。
- 是唯一一个在 JVM 规范中没有规定任何
OutOfMemoryError的区域。 - 在物理实现上通常通过 CPU 的寄存器完成。
虚拟机栈(Java Virtual Machine Stack)
- 定义:虚拟机栈描述的是 Java 方法执行的内存模型,每个线程运行时所需的内存空间。
- 结构:由多个栈帧(Stack Frame)组成,每个栈帧对应一个方法调用。
- 栈帧内容:
- 局部变量表(Local Variable Table)
- 操作数栈(Operand Stack)
- 方法返回地址(Return Address)
- 动态链接(Dynamic Linking)
- 附加信息
- 特点:
- 线程私有,生命周期与线程一致。
- 栈深度受限,方法递归调用过深可能引发
StackOverflowError。 - 不受垃圾回收机制管理。
本地方法栈(Native Method Stack)
- 定义:用于支持 JVM 调用本地方法(Native Method)所使用的内存空间。
- 特点:
- 与虚拟机栈功能类似,但为 Native 方法服务。
- 部分 JVM 可能将本地方法栈与虚拟机栈合二为一。
- 方法通常由 C/C++ 编写,用于与操作系统底层交互(如文件操作、网络通信等)。
- 方法使用
native关键字修饰,无 Java 实现。
线程共享区域
Java 堆(Heap)
- 定义:Java 堆是 JVM 所管理的最大一块内存区域,用于存放对象实例。
- 特点:
- 线程共享,几乎所有对象实例都在堆上分配。
- 是垃圾回收器(GC)管理的主要区域。
- 逻辑结构:
- 年轻代(Young Generation):存放短生命周期对象。
- Eden 区、From Survivor、To Survivor。
- 老年代(Old Generation):存放长生命周期对象。
- 年轻代(Young Generation):存放短生命周期对象。
- 版本差异:
- JDK 1.7:堆中包含方法区的实现(永久代)。
- JDK 1.8:方法区实现移出堆,使用元空间(Metaspace)存储,占用本地内存。
方法区(Method Area)
- 定义:用于存储类的元数据信息,包括类信息、常量池、静态变量、编译器编译后的代码等。
- 特点:
- 线程共享。
- 不同于堆,主要用于存储类结构信息。
- 实现演变:
- JDK 1.7:方法区基于永久代(Permanent Generation)实现,位于堆内存中,大小固定。
- JDK 1.8:方法区移至本地内存,称为 元空间(Metaspace),默认无上限,可根据系统内存自动扩展。
直接内存(Direct Memory)
- 定义:直接内存并非 JVM 运行时数据区的一部分,而是操作系统内存,通过 NIO 的
ByteBuffer进行分配。 - 作用:用于提高 I/O 操作的性能,绕过 JVM 堆内存的复制过程。
- 特点:
- JVM 不直接管理,需手动分配和释放。
- 分配和回收成本较高,但读写速度更快。
- 可被 Java 代码和本地系统代码共同访问。
- 使用场景:
- NIO(New I/O)中用于文件和网络的高效数据传输。
- 需要注意内存泄漏和资源释放。