JAVA面试-JVM篇 03-JVM运行时数据区哪些是线程私有的哪些是共享的
·
JAVA面试-JVM篇 03-JVM运行时数据区哪些是线程私有的哪些是共享的
文章概述
JVM运行时数据区是Java程序运行时的内存划分方案,理解哪些区域是线程私有的、哪些是共享的,是JVM调优和故障排查的基础。本文用一张总图、两张分类流程图和一张对比表格,帮你一次性理清。
一、整体架构一览
口诀:两栈一计数器私有,堆与方法区共享。
二、线程私有的三个区域
每个线程启动时都会独立创建一份,互不干扰。
1. 程序计数器(Program Counter Register)
- 当前线程所执行的字节码行号指示器
- 分支、循环、跳转、异常恢复等都依赖它
- 唯一一个不会抛出 OOM 的区域
2. Java虚拟机栈(Java Virtual Machine Stack)
每个方法调用都会创建一个栈帧入栈,方法结束则出栈。
| 栈帧组成 | 说明 |
|---|---|
| 局部变量表 | 存储方法参数和方法内定义的局部变量 |
| 操作数栈 | 字节码指令执行时的临时数据存储区 |
| 动态链接 | 指向运行时常量池中该方法的符号引用 |
| 方法出口 | 方法正常/异常返回时恢复上层调用者的状态 |
3. 本地方法栈(Native Method Stack)
为 native 方法服务。HotSpot 虚拟机将它与虚拟机栈合二为一。
三、线程共享的两个区域
所有线程共享同一份数据,是垃圾回收和内存调优的重点关注区域。
1. 堆(Heap)
- Java 内存管理中最大的一块
- 所有对象实例和数组都在这里分配
- 垃圾回收的主战场,分代回收的基础
- 可细分为:年轻代(Young Gen)、老年代(Old Gen)
2. 方法区(元空间 Metaspace)
- 存储已被加载的类信息、常量、静态变量、JIT编译后的代码
- JDK8 后用元空间替代永久代,从JVM内存移到本地内存
- 包含运行时常量池,存放编译期生成的字面量和符号引用
四、完整总结
| 区域 | 线程私有/共享 | 存储内容 | 是否OOM |
|---|---|---|---|
| 程序计数器 | 私有 | 当前线程执行的字节码地址 | 否 |
| Java虚拟机栈 | 私有 | 栈帧(局部变量表、操作数栈等) | 是 |
| 本地方法栈 | 私有 | native方法调用信息 | 是 |
| 堆 | 共享 | 对象实例、数组 | 是 |
| 方法区/元空间 | 共享 | 类信息、常量、静态变量、JIT代码 | 是 |
更多推荐

所有评论(0)