JAVA对象分配中的逃逸分析

前言:new出来的对象一定是储存在堆中的吗?

1. JIT简介


  • JIT 是 just in time 的缩写, 也就是即时编译编译器。使用即时编译器技术,能够加速 Java 程序的执行速度。
  • 首先,我们大家都知道,通常通过 javac 将程序源代码编译,转换成 java 字节码,JVM 通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译。很显然,经过解释执行,其执行速度必然会比可执行的二进制字节码程序慢很多。为了提高执行速度,引入了 JIT 技术。
  • 在运行时 JIT 会把翻译过的机器码保存起来,以备下次使用,因此从理论上来说,采用该 JIT 技术可以接近以前纯编译技术。
  • 代码在执行过程中,JIT会为我们做很多优化,其中有一种技术叫做逃逸分析。

2. 逃逸分析


当一个对象被定义之后,可能会被外部对象引用,称之为方法逃逸;也有可能被其他线程所引用,称之为线程逃逸

回归到我们的主题对象是一定会被分配到堆中的吗?

public class Stack {
    public static void main(String[] args) throws InterruptedException {

        Stack stack = new Stack();
        for (int i = 0; i < 1000000; i++) {
            stack.add();
        }
        Thread.sleep(Long.MAX_VALUE);

    }

    public void add() {
        Student student = new Student();
    }
}

上面这段代码就是不停的调用add()方法生成一个Student对象。该方法创建Student对象没有被外界所引用,则会被我们的JIT的逃逸分析所优化来减轻我们不停创建对象导致堆内存压力过大,会将我们的部分对象分配到栈帧中,在执行完方法后出栈销毁。
验证如下(从JDK7开始默认是开启逃逸分析的)

 num     #instances         #bytes  class name
----------------------------------------------
   1:          6470        4002904  [B
   2:         17305        3255472  [C
   3:        100087        1601392  Student

我们可以看到Student的在堆内存中只有100087对象实例。


现在我们来关闭逃逸分析 -XX:-DoEscapeAnalysis
在这里插入图片描述

 num     #instances         #bytes  class name
----------------------------------------------
   1:       1000000       16000000  Student
   2:          6470        4002952  [B
   3:         17307        3255864  [C

当我们关闭了逃逸分析之后可以看到堆内存中存在1000000个Student对象实例。

希望大家知道创建的对象不一定都是存放在堆内存中的。

如何用idea查看堆内存实例数量。
在这里插入图片描述

@一名互联网的吊车尾

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值