

今天本文的内容就针对刚刚模拟面试两个问题
1.对象的创建过程
2.对象的内存布局
以下内容基于HotSpot VM 分代模型

这张图其实就能完整的说明一个对象的创建过程到底发生了什么,很多朋友可能一下看不懂,那么我们就跟着左上角的一步一步来:
通过这张流程图和步骤解析大家应该对一个对象的创建过程有一个很清晰的概念了,但是其中还是有很多小细节会被忽略,为什么jvm会在对象的创建过程中大作文章,会分这么多种情况?为了让大家更深入的能够理解它,我们就再来看看下面这几个问题:
首先栈是线程私有的,将对象优先分配在栈中,可以通过pop直接将对象的所有信息,空间直接清除,当线程消亡的时候也可以直接清理这一块儿TLAB区域。
大对象需要连续的空间来存储,如果不存入老年代对jvm说就可能是一个负担,如果没有足够的空间就有可能导致提前触发gc来清理空间来安置大对象。
TLAB是线程本地缓冲区,TLAB的好处就是防止不同线程创建对象选择同一块儿内存区域而产生竞争,会使其概率大大减少。
根据根可达算法,jvm会从开始寻找到所有正在使用的对象,没有使用的就是垃圾,通常情况下,很多对象都是用完就抛弃的,所以真正在Survivor区长时间存活的对象非常少,将这部分对象从一个Survivor区转到另一个Survivor区后,就可以直接对这个Survivor区进行全量的空间回收了,效率会很高。
作者可不是标题党,哈哈,所以我们回到文章的标题,Object o = new Object();到底占用多少个字节?这道题的目的其实就是考验看你对对象的内存布局了解的是否清晰,先上图:

在java中对象的内存布局分为两种情况,非数组对象和数组对象,数组对象和非数组对象的区别就是需要额外的空间存储数组的长度length。
对象头又分为MarkWord和Class Pointer两部分。
moon在上文特意标注了32位系统和64位系统不同区域占用空间大小的区别,这是因为对象指针在64位JVM下的寻址更长,所以想比32位会多出来更多占用空间。
但是现在假设一个场景,公司现在项目部署的机器是32位的,你们老板要让你将项目迁移到64位的系统上,但是又因为64位系统比32位系统要多出更多占用空间,怎么办,因为正常来说我们是不需要这一部分多余空间的,所以jvm已经帮你考虑好了,那就是指针压缩。
-XX:+UseCompressedOops 这个参数就是JVM提供给你的解决方案,可以压缩指针,将占用的空间压缩为原来的一半,起到节约空间的作用,classpointer参数大小就受到其影响。
通过刚才内存布局的学习后,这个问题就很好回答了,面试官其实就是想问你对象的内存布局是怎样的,我们这里就针对这个问题的结果分析下,这里分两种情况:
今天的文章和大家介绍了一个对象的创建过程,从它的出生到死亡,都经历了什么?也和大家详细的说明了对象的内存布局,深入解剖了一下对象的身体构造,这下面试官再问你,可就有的聊了,这篇文章的内容还是比较肝的,需要大家认真阅读一下 。