文章目录
- 一、线程私有区域
-
-
- [1️⃣ 程序计数器(Program Counter Register)](#1️⃣ 程序计数器(Program Counter Register))
- [2️⃣ Java 虚拟机栈(Java Stack)](#2️⃣ Java 虚拟机栈(Java Stack))
- [3️⃣ 本地方法栈(Native Method Stack)](#3️⃣ 本地方法栈(Native Method Stack))
-
- 二、线程共享区域(大家一起用)
-
-
- [4️⃣ 堆(Heap)⭐重点](#4️⃣ 堆(Heap)⭐重点)
- [5️⃣ 方法区(Method Area)](#5️⃣ 方法区(Method Area))
- [6️⃣ 运行时常量池(Runtime Constant Pool)](#6️⃣ 运行时常量池(Runtime Constant Pool))
-
- [三、JDK8 之后的重要变化(⚠️ 面试常问)](#三、JDK8 之后的重要变化(⚠️ 面试常问))

| 区域 | 线程 | 主要内容 |
|---|---|---|
| 程序计数器 | 私有 | 当前指令位置 |
| 虚拟机栈 | 私有 | 方法调用 |
| 本地方法栈 | 私有 | Native 方法 |
| 堆 | 共享 | 对象实例 |
| 方法区 | 共享 | 类信息 |
| 运行时常量池 | 共享 | 常量、符号引用 |
一、线程私有区域
1️⃣ 程序计数器(Program Counter Register)
📍 干嘛的
-
记录当前线程正在执行的字节码行号
-
JVM 靠它知道"下一条指令去哪"
📌 特点
-
线程私有
-
占用内存极小
-
唯一不会抛
OutOfMemoryError的区域
🧠 一句话记忆
👉 JVM 的"书签"
2️⃣ Java 虚拟机栈(Java Stack)
📍 干嘛的
-
每个方法调用都会创建一个栈帧
-
栈帧中包含:
-
局部变量表
-
操作数栈
-
动态链接
-
方法返回地址
-
📌 特点
-
线程私有
-
方法调用 → 入栈
-
方法结束 → 出栈
💥 常见异常
-
StackOverflowError:递归太深 -
OutOfMemoryError:栈空间不够
🧠 一句话记忆
👉 方法调用的"通话记录"
3️⃣ 本地方法栈(Native Method Stack)
📍 干嘛的
-
给 Native 方法(JNI) 用的栈
-
例如调用 C / C++ 代码
📌 特点
-
线程私有
-
和虚拟机栈作用类似,只是服务对象不同
🧠 一句话记忆
👉 Java 调用"外援"的专用通道
二、线程共享区域(大家一起用)
4️⃣ 堆(Heap)⭐重点
📍 干嘛的
- 几乎所有对象实例和数组都在这里分配
📌 特点
-
线程共享
-
JVM 中 最大的一块内存
-
垃圾回收(GC)的主战场
🧱 常见细分(HotSpot)
-
新生代
-
Eden
-
Survivor(From / To)
-
-
老年代
💥 常见异常
OutOfMemoryError: Java heap space
🧠 一句话记忆
👉 对象的"集中居住区"
5️⃣ 方法区(Method Area)
📍 干嘛的
-
存储 类级别信息
-
类结构信息
-
方法信息
-
运行时常量池
-
静态变量
-
📌 特点
-
线程共享
-
逻辑上属于堆的一部分
💥 异常
OutOfMemoryError: Metaspace(JDK8+)
🧠 一句话记忆
👉 类的"说明书仓库"
6️⃣ 运行时常量池(Runtime Constant Pool)
📍 干嘛的
-
存放:
-
字面量(字符串、数字)
-
符号引用(类、方法、字段)
-
📌 特点
-
属于方法区的一部分
-
运行期间也可以动态加入
🧠 一句话记忆
👉 JVM 的"常量词典"
三、JDK8 之后的重要变化(⚠️ 面试常问)
| 版本 | 变化 |
|---|---|
| JDK7 | 方法区在堆中(永久代 PermGen) |
| JDK8 | 移除永久代 |
| JDK8+ | 方法区实现为 元空间 Metaspace(使用本地内存) |
| 🧠 一句话记忆 | |
| 👉 永久代下岗了,元空间接班,用的是系统内存 |