前言

本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构和参考文献请见100个问题搞定Java虚拟机

正文

在回答这个问题前,先要明白 JVM 中创建一个对象要花费什么?

可以从时间和空间两个角度来考虑

  1. 时间

new关键字在虚拟机中是怎样的一个过程?JVM构造对象的步骤都有哪些?

  1. 空间

对象在堆内存中的存储布局是怎样的?

从上面就可以看出,Java 对象实际上给 JVM 带来了很多负担,也给服务器带来了麻烦。

故避免创建 Java 对象能更好的提高性能。

但是有些 Java 对象是不可避免的,那么在什么情况下对象分配会被优化呢?

在什么情况下对象分配会被优化呢?

如果对象的生命周期只存在于一个线程或者方法里面,不会逃逸(逃逸分析的过程)。

那么我们可以将这个对象只在栈上进行分配,这样随着方法调用结束,栈帧的生命周期完结,对象自动就跟着栈帧而消亡了,不需要麻烦 JVM 来进行垃圾收集的。

这种优化方式叫栈上分配。

此外,我们还可以将对象打散成一个个的基本数据类型(JVM 的基本数据类型不同于 Java),这样也存储在栈或者寄存器里面。

这种优化方式叫标量替换。

Graal 编译器还可以直接优化掉某些条件判断语句里面的创建对象的过程(部分逃逸分析)。

更详细的内容可以参考我的这篇博客——一篇文章搞懂逃逸分析,栈上分配,标量替换,同步消除,锁消除之间的区别

JVM 中所有的对象只在堆上分配吗?

不是。

从上面的分析可以看出,JVM 中的对象在逃逸分析后如果判定不逃逸,就会采取栈上分配或者标量替换的优化手段(HotSpot 虚拟机采取的是标量替换),

分配在栈或者寄存器里面。

上一篇 下一篇