You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8中方法内创建的对象存储位置:栈还是堆?

Java 8中方法内部创建的对象存储位置解析

嘿,这个问题问得相当精准!咱们直接给结论:你示例代码里new A()创建的对象实例本身是存储在堆内存中的,而方法test()里的局部变量m(也就是指向这个对象的引用)才会放在栈内存里。

先把栈和堆的分工掰扯清楚:

  • 栈内存的核心职责是存局部基本类型变量、对象引用变量,还有方法调用时生成的栈帧(包含方法参数、返回地址等信息)。它的生命周期完全和方法调用绑定,方法执行完毕,对应的栈帧就会被弹出栈,里面的局部变量也就跟着失效了。
  • 堆内存是Java里所有对象实例的“根据地”——不管你是在方法里new的、作为类的成员变量,还是其他场景生成的对象,只要是通过new关键字创建的实例,统统都在堆里。堆的回收由GC(垃圾回收器)负责,和方法是否执行完没有直接关系,只有当对象不再被任何引用指向时,GC才会考虑回收它占用的堆空间。

再对着你的示例代码拆解一下执行过程:

public class A {}
public class B {
    public void test(){
        A m = new A(); // 这一行其实分两步执行
    }
}

当test()方法被调用时:

  1. 先执行new A():JVM会在堆内存中分配一块空间,创建A类的对象实例,完成初始化(如果A有构造方法或成员变量的话)。
  2. 接着把堆中这个对象的内存地址赋值给局部变量m:而m这个引用变量,是存储在当前test()方法对应的栈帧里的。

你提到的“情况1”没写完,估计是在纠结会不会有特殊情况让对象跑到栈上?其实在Java 8里,JVM有个逃逸分析的优化机制,默认是开启的。如果JVM分析出某个对象不会“逃逸”出当前方法(也就是不会被方法外的变量引用),可能会把对象拆解成基本类型变量直接存在栈上(也就是标量替换),避免堆分配。但这是JVM底层的自动优化,从开发者的代码视角来看,我们依然可以认为new出来的对象实例本质上是属于堆内存的范畴——毕竟这种优化是透明的,不需要我们在代码里做任何特殊处理。

最后再划个重点:

  • 局部引用变量m → 栈内存
  • new A()创建的对象实例 → 堆内存

内容的提问来源于stack exchange,提问作者Brixton Weiss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:54:48