是不是所有的对象和数组都会在堆内存分配空间

熟看了java编译原理等多本大神级别书籍后,小明信心满满的去面试字节跳动了,跳动的面试官说:小伙,来给我讲一下是不是所有的对象和数组都会在堆内存分配空间?

 

小明不由一喜,昨天正好我看了相关jvm的书籍,堆中主要存放对象,即通过new关键字创建的对象。当场哈哈大笑:没错,面试官你太威武了,所有的对象和数组都存在堆中。当场从jvm原理:方法区、虚拟机栈、本地方法栈、堆、程序计数器讲起,说到堆内主要存放对象,栈中存放一些基本类型的变量数据(int/short/long/byte/float/double/Boolean/char)和对象引用。内心狂喜,但实际是这样吗?

 

正好在前几天发了两篇关于java逃逸分析的文章,但是发现大家看的不多,当大家都在最求mysql优化,mongo优化等等的时候,有没有想过jvm有一种优化技术叫做逃逸分析。

 

1.   JVM优化之逃逸分析与分配消除

2.  JVM优化之逃逸分析及锁消除

 

jvm在编译阶段引入了JIT(即时编译) 技术,而随着这种技术的成熟,栈上分配、标量替换优化技术也产生了一些微妙的变化,所有的对象都分配到堆上也渐渐变得不那么“绝对”了。

 

为了方便大家理解逃逸分析,给大家献上两段网上找的代码

 

大家可以观察,在第一段代码中StringBuffer对象被该方法之外的给利用了,也就是该对象逃逸出了该方法体。相反第二段代码就将对象的值转化为常量返回给了调用方,该对象就在内部被消化了,jvm的逃逸分析也针对的就是这种情况。

 

在Java代码运行时,通过JVM参数可指定是否开启逃逸分析,
 -XX:+DoEscapeAnalysis :表示开启逃逸分析
 -XX:-DoEscapeAnalysis : 表示关闭逃逸分析

 

下面我们开始举个例子:

这是一段测试代码,其中User对象只被alloc调用了。我们接下来重启两次jvm,一次执行代码

-Xmx4G -Xms4G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

另一次执行:

-Xmx4G -Xms4G -XX:+DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

我们通过jmap命令来查看结果:第一次结果

第二次结果:

不难看出在开启逃逸分析的情况下 堆内存中的对象数量为8万多比没开启的情况下的100万少了非常多。

所以我们也基本上能看出,跳动的面试官想问的不是书本上的死知识。

总结一下:

在Java虚拟机中,对象是在Java堆中分配内存的,这是一个普遍的常识。但是,有一种特殊情况,那就是如果经过逃逸分析后发现,一个对象并没有逃逸出方法的话,那么就可能被优化成栈上分配。这样就无需在堆上分配内存,也无须进行垃圾回收了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值