首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试官:是不是所有的对象和数组都会在堆内存分配空间

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

作者头像
哲洛不闹
发布2019-08-20 11:46:52
7430
发布2019-08-20 11:46:52
举报
文章被收录于专栏:java一日一条java一日一条

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

参考:Hollis公众号

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java一日一条 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档