jvm运行时数据子系统
jvm的运行时区域分为6部分
flowchart TD
A[JVM Runtime Data Areas]
A --> B[堆 Heap]
A --> C[虚拟机栈 JVM Stack]
A --> D[本地方法栈 Native Stack]
A --> E[程序计数器 PC Register]
A --> F[方法区 Method Area]
A --> G[直接内存 Direct Memory]
classDef jvm fill:#f9e6ff,stroke:#333
classDef heap fill:#e6f7ff,stroke:#3498db
classDef stack fill:#e8f5e9,stroke:#2ecc71
classDef meta fill:#ffe6cc,stroke:#ff9900
classDef native fill:#ffcccc,stroke:#e74c3c
class A jvm
class B heap
class C,D stack
class F meta
class G native
模块详细说明:
1. 堆 (Heap Area) 🧱
graph LR
堆 --> Young[年轻代]
堆 --> Old[老年代]
Young --> Eden[伊甸区]
Young --> S0[Survivor0]
Young --> S1[Survivor1]
- 职责:所有对象实例和数组的存储池
- 特性:
- 所有线程共享
- 生命周期:对象创建到垃圾回收
- 区域划分:
- 年轻代 (Eden, Survivor0, Survivor1)
- 老年代 (Tenured)
- G1/ZGC等新型回收器有不同的分区策略
- 异常:
OutOfMemoryError当无法分配新对象时
2. 方法区 (Method Area) 📚
graph TD
MethodArea --> 类[类信息]
MethodArea --> 常量池[运行时常量池]
MethodArea --> 静态[静态变量]
MethodArea --> JIT[JIT编译代码]
- 职责:类结构信息存储中心
- 关键内容:
- 类全名、父类/接口名
- 方法字节码/字段描述符
- 运行时常量池(重要子模块)
static final常量
- 演进:
- JDK7:字符串常量池移至堆中
- JDK8+:被 Metaspace 取代(使用本地内存,如下图)
graph LR RAM[物理内存] --> OS OS --> JVM_Heap[JVM堆空间] OS --> Native_Memory[本地内存空间] Native_Memory --> Metaspace Native_Memory --> DirectBuffer[直接内存] Native_Memory --> JNI_Memory[JNI内存]
3. Java 虚拟机栈 (JVM Stacks) 🧾
graph TB
Stack --> 栈帧1[栈帧 - 方法A]
Stack --> 栈帧2[栈帧 - 方法B]
栈帧1 --> 局部变量[局部变量表]
栈帧1 --> 操作数[操作数栈]
栈帧1 --> 动态[动态链接]
栈帧1 --> 返回[返回地址]
-
线程关系:每线程独享一个栈
-
核心功能:方法调用时压入栈帧,返回时弹出
-
栈帧结构:
组件 说明 局部变量表 基本类型 + 对象引用 操作数栈 字节码指令操作区 动态链接 指向常量池的引用 返回地址 方法退出后回到的位置 -
异常:
StackOverflowError(深度超限)
4. 本地方法栈 (Native Method Stack) 🌐
graph LR
NativeStack --> JNI[Java Native Interface]
JNI --> Native[本地库]
- 专用场景:执行非Java方法(如C/C++函数)
- 与JVM栈区别:
- 无字节码操作
- 直接调用操作系统API
- 支持JNI规范的所有本地操作
5. 程序计数器 (Program Counter Register) 📍
graph LR
PC[Java方法] --> 指令1[字节码指令地址]
Native方法 --> undefined
- 核心作用:保存下一条执行的字节码地址
- 特殊性:
- 唯一没有
OutOfMemoryError的区域 - 线程私有,保证线程切换后能正确恢复
- 执行本地方法时为
undefined
- 唯一没有
补充区域:
6.直接内存 (Direct Memory) ⚡
graph LR
A[NIO Direct Buffer] --> B(Native Memory)
- 非JVM规范区域
- 用途:NIO使用的堆外内存
- 优势:减少JVM堆与本地堆的数据拷贝
- 管理:通过
Unsafe类分配回收 - 异常:
OutOfMemoryError(超出系统内存)
以下是一个清晰的 JVM 运行时数据区域示意图及其说明
flowchart TD
A[JVM Runtime Data Areas]
A --> B[Heap Area<br/>对象实例存储<br/>所有线程共享<br/>运行时常量池<br/>GC管理区域]
A --> C[Method Area<br/>类元数据存储<br/>静态变量]
A --> D[Java Virtual Machine Stacks<br/>线程私有<br/>栈帧管理]
A --> E[Native Method Stack<br/>线程私有<br/>本地方法执行]
A --> F[Program Counter Register<br/>线程私有<br/>指令位置记录]
A --> G[Native Memory<br/>直接内存<br/>Matespace<br/>JNI<br/>mmap内存映射]
B --> C1[Runtime Constant Pool<br/>符号引用解析<br/>字面量存储]
D --> D1[Stack Frame 1]
D --> D2[Stack Frame 2]
D1 --> D1a[Local Variables<br/>局部变量]
D1 --> D1b[Operand Stack<br/>操作数]
D1 --> D1c[Dynamic Linking<br/>符号引用]
D1 --> D1d[Return Address<br/>返回位置]