一、三大内存区域

1. 虚拟机栈(栈)

  • 存放:局部变量、方法参数、引用地址
  • 生命周期:随方法调用创建,方法结束立即销毁
  • 线程私有,速度极快,空间小
  • 基本类型直接存栈,对象引用存栈,对象实体在堆

2. 堆 Heap

  • 存放:所有对象实例、数组
  • 线程共享,GC 主要回收区域
  • 分代:新生代 + 老年代(JDK8 彻底废除永久代)
  • 空间大、分配慢,频繁触发 GC

3. 元空间 Metaspace(JDK8+)

  • 替代之前永久代
  • 存放:类元信息、方法字节码、常量池、方法注解
  • 直接使用本地内存,不受 JVM 堆内存限制
  • 默认自动扩容,很少溢出

极简总结

  • 栈:存变量 + 引用,快、私有、短命
  • 堆:存对象实例,慢、共享、GC 回收
  • 元空间:存类结构信息,本地内存

二、逃逸分析(JVM 核心优化)

1. 定义

JVM 在编译时分析对象作用域:判断对象是否会逃出当前方法 / 线程

2. 两种情况

  1. 未逃逸:对象只在当前方法内使用,不会传出
  2. 已逃逸:对象被返回、赋值给成员变量、多线程共享

3. 开启关闭

  • JDK1.6 默认开启
  • 参数:

plaintext

-XX:+DoEscapeAnalysis 开启
-XX:-DoEscapeAnalysis 关闭

三、栈上分配(逃逸分析最核心优化)

1. 原理

对象没有发生逃逸 → JVM 不在堆创建对象,直接分配到虚拟机栈

2. 好处

  1. 栈内存自动回收,不用走 GC
  2. 大幅减少堆对象,降低 GC 压力
  3. 执行速度暴涨

3. 分配规则

满足全部条件才会栈上分配:

  1. 对象只在方法内部使用
  2. 不返回、不赋值全局变量
  3. 无多线程共享
  4. 逃逸分析开启

4. 反例(不能栈分配)

java

运行

// 对象逃逸,只能堆分配
public User getUser(){
    User u = new User();
    return u;
}

5. 正例(可栈上分配)

java

运行

public void test(){
    User u = new User();
    u.setName("test");
    // 仅内部使用,无逃逸 → 栈上分配
}

四、衍生优化(逃逸分析附带)

  1. 标量替换把对象拆解成多个局部变量,直接存栈,连对象都不创建,性能最强。
  2. 同步消除局部对象无多线程竞争,自动去掉 synchronized 锁。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐