导读:本期聚焦于小伙伴创作的《怎么通过分析 JVM 的逃逸分析(Escape Analysis)理解为何局部对象可以在栈上分配》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《怎么通过分析 JVM 的逃逸分析(Escape Analysis)理解为何局部对象可以在栈上分配》有用,将其分享出去将是对创作者最好的鼓励。

JVM的内存分配规则中,对象默认分配在堆上,由垃圾回收器负责回收,但逃逸分析优化打破了这个默认规则,让部分局部对象可以直接分配在栈上,随方法栈帧的出栈自动销毁,不需要垃圾回收介入。

怎么通过分析 JVM 的逃逸分析(Escape Analysis)理解为何局部对象可以在栈上分配

什么是逃逸分析

逃逸分析是JVM在即时编译(JIT)阶段执行的一项优化分析,核心作用是判断新创建的对象的作用范围是否会逃逸出当前方法或者当前线程。如果对象的作用范围完全局限在方法内部,没有被外部方法引用,也没有被其他线程访问到,就称这个对象没有发生逃逸,此时JVM就可以对这个对象做一系列优化,栈上分配就是其中一项核心优化。

逃逸的两种常见场景

  • 方法逃逸:对象被作为返回值返回,或者被作为参数传递到了其他方法,导致对象的作用范围超出了当前方法。
  • 线程逃逸:对象被赋值给了类变量,或者被其他线程通过共享变量访问到,导致对象的作用范围超出了当前线程。

为什么无逃逸对象可以栈上分配

栈上的内存分配和回收效率远高于堆:栈帧是线程私有的,方法执行时创建栈帧,栈帧中包含局部变量表、操作数栈等空间,方法执行结束后栈帧直接出栈销毁,不需要额外的垃圾回收操作。而堆上的对象需要垃圾回收器判断存活状态,回收过程会消耗一定的性能。

如果逃逸分析判定对象没有发生逃逸,JVM就可以把这个对象的实例数据直接分配在当前方法的栈帧中,而不是堆上。当方法执行结束,栈帧销毁,这个对象占用的内存也直接被释放,完全不需要垃圾回收介入,能显著降低堆内存的分配压力和垃圾回收的频率。

代码示例验证逃逸分析与栈上分配

我们可以通过一段简单的代码来观察无逃逸对象的分配情况,首先需要开启JVM的逃逸分析相关参数,JDK 1.7之后逃逸分析是默认开启的,也可以手动指定参数:

// 逃逸分析相关JVM参数
// -XX:+DoEscapeAnalysis 开启逃逸分析(默认开启)
// -XX:-DoEscapeAnalysis 关闭逃逸分析
// -XX:+PrintGCDetails 打印垃圾回收详情
public class EscapeAnalysisTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        // 循环调用创建对象的方法
        for (int i = 0; i < 100000000; i++) {
            createNoEscapeObject();
        }
        long end = System.currentTimeMillis();
        System.out.println("执行耗时:" + (end - start) + "ms");
        // 防止程序提前退出,方便观察GC情况
        try {
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 创建的对象只在方法内部使用,没有逃逸
    private static void createNoEscapeObject() {
        // 局部对象,没有返回,也没有传递给其他方法
        User user = new User("test", 18);
        // 仅方法内部使用对象属性,没有外部引用
        int age = user.getAge();
    }

    static class User {
        private String name;
        private int age;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public int getAge() {
            return age;
        }
    }
}

当我们开启逃逸分析运行上述代码时,会发现执行耗时很短,并且几乎不会产生垃圾回收日志,因为User对象没有发生逃逸,全部在栈上分配,随方法栈帧出栈直接销毁。如果关闭逃逸分析,对象会全部分配在堆上,会频繁触发垃圾回收,执行耗时也会明显增加。

逃逸分析的其他优化

除了栈上分配,逃逸分析还会触发另外两项优化:

  • 标量替换:如果对象没有逃逸,JVM可能不会创建完整的对象结构,而是把对象的成员变量拆分成独立的标量(比如int、reference等),直接分配在栈上的局部变量表中,进一步减少内存占用。
  • 同步消除:如果对象没有发生线程逃逸,说明不会有多个线程同时访问这个对象,那么对象上的同步锁(比如synchronized修饰的代码块)就可以被消除,减少同步带来的性能开销。

注意事项

逃逸分析的优化并不是绝对的,JVM会根据运行时的实际情况判断是否执行优化。另外,栈的容量是有限的,如果对象占用的内存过大,即使没有逃逸,JVM也可能不会选择栈上分配,而是继续分配在堆上。开发者在写代码时,可以尽量缩小对象的作用范围,避免不必要的对象逃逸,让JVM更好地执行优化,提升程序性能。

JVM逃逸分析Escape_Analysis栈上分配修改时间:2026-07-03 23:27:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。