一、整体认识
在 JVM 内存结构中:
-
栈(Stack):线程私有,管理方法调用
-
堆(Heap):线程共享,存储对象
👉 一句话总结:
栈管运行,堆管存储
二、虚拟机栈(Stack)详解
1. 什么是虚拟机栈
虚拟机栈是每个线程独有的内存区域,随着线程创建而创建,线程结束而销毁。
2. 栈的核心结构:栈帧
每次方法调用,都会创建一个栈帧(Stack Frame)
栈帧包含:
-
局部变量表
-
操作数栈
-
动态链接
-
方法返回地址
3. 栈的执行流程
java
public void methodA() {
methodB();
}
执行过程:
-
methodA 入栈
-
调用 methodB → methodB 入栈
-
methodB 执行完 → 出栈
-
methodA 继续执行
👉 特点:
先进后出(FILO)
4. 局部变量表
存储:
-
基本类型(int、double 等)
-
对象引用(不是对象本身)
👉 示例:
java
int a = 10;
User user = new User();
-
a 存在栈中
-
user 是引用(地址)在栈中
-
对象在堆中
5. 常见异常
1. 栈溢出
bash
java.lang.StackOverflowError
原因:
-
方法递归太深
-
栈帧过多
2. 栈内存不足(少见)
bash
OutOfMemoryError: unable to create new native thread
原因:
- 线程过多
三、堆(Heap)详解
1. 什么是堆
堆是 JVM 中最大的一块内存区域,所有线程共享。
👉 作用:
存储所有对象实例
2. 堆的结构(重点)
堆分为:
(1)新生代(Young Generation)
-
Eden 区
-
Survivor 区(S0、S1)
(2)老年代(Old Generation)
存放:
-
长期存活对象
-
大对象
3. 对象创建流程
java
User user = new User();
过程:
-
在 Eden 分配内存
-
初始化对象
-
引用指向该对象
4. 对象晋升过程
-
Eden → Survivor
-
多次 GC 后 → 老年代
5. 堆的垃圾回收
堆是 GC 的主要区域:
-
新生代:Minor GC(频繁)
-
老年代:Major GC / Full GC(较少)
6. 常见异常
1. 堆内存溢出
bash
java.lang.OutOfMemoryError: Java heap space
原因:
-
对象过多
-
内存泄漏
四、栈 vs 堆 核心区别(面试重点)
| 对比项 | 栈(Stack) | 堆(Heap) |
|---|---|---|
| 是否共享 | ❌ 线程私有 | ✅ 线程共享 |
| 存储内容 | 方法调用、局部变量 | 对象实例 |
| 生命周期 | 随线程 | 随 GC |
| 分配速度 | 快 | 相对慢 |
| 是否 GC | ❌ 不需要 | ✅ 需要 |
| 是否可能溢出 | StackOverflowError | OOM |
五、经典面试问题
1. 对象到底存在哪?
java
User user = new User();
👉 分析:
-
user(引用)→ 栈
-
new User()(对象)→ 堆
2. 方法调用发生在哪?
👉 在栈中(栈帧)
3. 为什么栈不需要 GC?
👉 因为:
-
生命周期明确(方法结束自动释放)
-
不存在"垃圾对象"
4. 为什么堆需要 GC?
👉 因为:
-
对象生命周期不确定
-
存在无用对象
六、深入理解(加分项)
1. 为什么栈快?
原因:
-
内存连续
-
由编译器管理
-
无需 GC
2. 为什么堆慢?
原因:
-
动态分配
-
需要 GC
-
存在碎片
3. 引用传递本质
Java 中:
👉 传递的是"值",但对象是引用值
七、实际问题分析
场景1:递归导致栈溢出
java
public void test(){
test();
}
👉 无限入栈 → StackOverflowError
场景2:堆内存泄漏
java
List list = new ArrayList();
while(true){
list.add(new Object());
}
👉 对象一直存在 → OOM
八、调优建议(实战)
1. 栈大小设置
bash
-Xss1m
👉 每个线程栈大小
2. 堆大小设置
bash
-Xms512m
-Xmx1024m
3. 排查工具
-
jvisualvm
-
jmap
-
MAT
九、一句话总结
👉 栈和堆本质区别:
栈负责方法执行,堆负责对象存储
十、终极理解(面试加分)
👉 可以这样总结:
-
栈解决的是"程序如何运行"
-
堆解决的是"数据存在哪里"
-
GC 解决的是"数据什么时候清理"