浅谈-栈上分配和逃逸分析

16 篇文章 0 订阅

前体

让我们先来看一段代码

String s = "a" + "b"

请问这代码产生了几个对象?
有的人可能会说3个
有的人可能会说1个

这里先不说答案,我们先回顾下什么是对象,对象放在哪里?
一般情况下,我们把放在堆里面的称之为对象
也就意味着对象只能放在堆里面

其实并不是这样,对象其实并不是只能放在堆里面
它也能放在栈里面

这里就要讲到第一个概念:

栈上分配

public void test(){
   User user = new User();

   user....
}

正常情况下
当User对象使用完后,并且之后一段时间内都不再被用到时
对象就会在堆中等待被gc回收
但并不是马上被回收,而是等待一个空间的时间
而gc并不能由我们控制,所以gc的自动回收机制很不是很好

那么这里就有一个疑问?
既然这个对象用完后,就不再被使用
为何要放到堆里面等待被回收呢,何不放在栈里面用完就被弹出去不是很好嘛!

等对象一旦用完,就马上被释放掉 这就是栈上分配的原理

那肯定又有人说既然这个机制这么好,我们都把对象放在栈里不是更好吗?!
其实不见得
这里就要引入第二个概念

逃逸分析

逃逸分析的原理:
就是分析这个对象的引用有没有逃出栈的范围

情景一

public void test(){
   User user = new User();

   user....

   return user;
}

当user使用后,不能马上被回收掉
如果被回收掉了
这是 test 的返回结果要被其他方法进行使用,就会报错
这是对象就绝对不能放在栈内存中,只能放在堆里面

情景二

public void test(User user){

   user....
}

上述情况中的user来自更大范围域中,
它的作用域远远大于test
不能在 test 方法结束后,就被回收掉

逃逸分析在分析对象时,会考虑
对象引用要是放在更大的范围中被引用,就绝对不能把对象放在栈里面
但发现对象逃不是栈的范围,就能被放入栈里面

所以对象不仅可以放在堆中,也能放在栈中


前体分析

所以回到我们最早的案例

String s = "a" + "b"

println(s)

答案肯定是

ab

那么到底产生多少对象,我们可以通过字节码进行查看

在这里插入图片描述
看到 a 了吗?
看到 b 了吗?
我们只能看到 ab

结论

公式中只产生了一个对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值