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()方法被调用时:
- 先执行
new A():JVM会在堆内存中分配一块空间,创建A类的对象实例,完成初始化(如果A有构造方法或成员变量的话)。 - 接着把堆中这个对象的内存地址赋值给局部变量
m:而m这个引用变量,是存储在当前test()方法对应的栈帧里的。
你提到的“情况1”没写完,估计是在纠结会不会有特殊情况让对象跑到栈上?其实在Java 8里,JVM有个逃逸分析的优化机制,默认是开启的。如果JVM分析出某个对象不会“逃逸”出当前方法(也就是不会被方法外的变量引用),可能会把对象拆解成基本类型变量直接存在栈上(也就是标量替换),避免堆分配。但这是JVM底层的自动优化,从开发者的代码视角来看,我们依然可以认为new出来的对象实例本质上是属于堆内存的范畴——毕竟这种优化是透明的,不需要我们在代码里做任何特殊处理。
最后再划个重点:
- 局部引用变量
m→ 栈内存 new A()创建的对象实例 → 堆内存
内容的提问来源于stack exchange,提问作者Brixton Weiss
相关产品推荐
相关产品推荐

