对象一定是在堆中创建的吗?

109 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情

对象一定是在堆中创建的吗?

这个问题就是要思考对象一定是在堆中创建吗?
java 中几乎所有的对象都是在堆中创建,这个里面不是绝对的,所以对象不一定都是在堆中进行创建的。
首先来看一下下面这张图,当我们 new 一个对象的时候如果这个代码或者对象是一个热点对象、代码的话,这部分代码和对象就会通过JIT的即时编译器进行解释成本地的机器代码。
如果这部分代码不是热点代码,那么它一定是在堆中分配。

image.png

但是如果创建的这个对象是热点代码的话,这部分代码是会触发 JIT 的即时编译,那么在JIT即时编译器里面呢还有一系列的优化技术。

比如它可以判断出 new 出来的这个对象它是否能逃逸,比如说是否能逃逸出这个方法,或者说是能否逃逸出这个线程,如果发现这个对象不能逃逸出这个方法,或者不能逃逸出这个线程的话,那么它就会判断是否开启标量替换。
那么什么是标量替换呢,我们知道在堆中间对象中重要的是它的成员变量,这些成员变量是否能在栈中进行替换,如果当这个对象能在栈中进行替换的话,这个对象就会走栈中进行分配。

如果这段代码已经触发了 JIT 即时编译器,并且它符合逃逸的条件,同时 jvm 开启了标量替换的话,这样的对象就不一定会在堆中进行创建了,而是会分配在栈中进行创建,这个分配方式称之为栈上分配。
所以对象不一定都是在堆中进行创建的。