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 栈合并)。
- 异常:
StackOverflowError
或OutOfMemoryError
。
(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 影响,展示理解深度。