内存模型:堆 / 栈 / 元空间、逃逸分析、栈上分配
·
一、三大内存区域
1. 虚拟机栈(栈)
- 存放:局部变量、方法参数、引用地址
- 生命周期:随方法调用创建,方法结束立即销毁
- 线程私有,速度极快,空间小
- 基本类型直接存栈,对象引用存栈,对象实体在堆
2. 堆 Heap
- 存放:所有对象实例、数组
- 线程共享,GC 主要回收区域
- 分代:新生代 + 老年代(JDK8 彻底废除永久代)
- 空间大、分配慢,频繁触发 GC
3. 元空间 Metaspace(JDK8+)
- 替代之前永久代
- 存放:类元信息、方法字节码、常量池、方法注解
- 直接使用本地内存,不受 JVM 堆内存限制
- 默认自动扩容,很少溢出
极简总结
- 栈:存变量 + 引用,快、私有、短命
- 堆:存对象实例,慢、共享、GC 回收
- 元空间:存类结构信息,本地内存
二、逃逸分析(JVM 核心优化)
1. 定义
JVM 在编译时分析对象作用域:判断对象是否会逃出当前方法 / 线程。
2. 两种情况
- 未逃逸:对象只在当前方法内使用,不会传出
- 已逃逸:对象被返回、赋值给成员变量、多线程共享
3. 开启关闭
- JDK1.6 默认开启
- 参数:
plaintext
-XX:+DoEscapeAnalysis 开启
-XX:-DoEscapeAnalysis 关闭
三、栈上分配(逃逸分析最核心优化)
1. 原理
对象没有发生逃逸 → JVM 不在堆创建对象,直接分配到虚拟机栈
2. 好处
- 栈内存自动回收,不用走 GC
- 大幅减少堆对象,降低 GC 压力
- 执行速度暴涨
3. 分配规则
满足全部条件才会栈上分配:
- 对象只在方法内部使用
- 不返回、不赋值全局变量
- 无多线程共享
- 逃逸分析开启
4. 反例(不能栈分配)
java
运行
// 对象逃逸,只能堆分配
public User getUser(){
User u = new User();
return u;
}
5. 正例(可栈上分配)
java
运行
public void test(){
User u = new User();
u.setName("test");
// 仅内部使用,无逃逸 → 栈上分配
}
四、衍生优化(逃逸分析附带)
- 标量替换把对象拆解成多个局部变量,直接存栈,连对象都不创建,性能最强。
- 同步消除局部对象无多线程竞争,自动去掉
synchronized锁。
更多推荐


所有评论(0)