面试官被欺负:new Object()到底占用几个字节?
发布网友
发布时间:2024-10-23 20:24
我来回答
共1个回答
热心网友
时间:2024-11-01 12:34
面试官经常提出的一个刁钻问题:`new Object()`究竟占用多少字节?解答这个问题,首先需理解堆内布局及Java对象在内存中的布局。
通过下面的代码片段,我们可以观察到`obj1`与`obj2`在内存中的区别。`obj1`位于方法区,`obj2`则属于栈内存。
对象在内存中的布局分为三部分:对象头、实例数据及对齐填充。以64位操作系统为例(不考虑指针压缩),Java对象布局如下图所示。
对象头中包含的Mark Word,其详细信息在`synchronized`锁升级原理中有详述。对齐填充不是必须的,若对象头和实例数据总和为8字节的倍数,则无需填充。
了解Java内存模型后,我们回到问题本身:`new Object()`在内存中占用多少字节?以64位操作系统为例,`new Object()`的占用大小有两套情况。
进行验证,引入依赖,新建示例代码并输出结果。开启与关闭指针压缩,得到结果为16字节和16字节。这显示默认开启了指针压缩。
进一步,我们分析对象中包含属性时的大小。创建新类,内含byte属性。在开启与关闭指针压缩的场景下,分别输出类大小。开启指针压缩为16字节,关闭为24字节,显示了指针压缩的优势。
访问对象时,我们通常采用两种方式:句柄访问与直接指针访问。句柄访问在对象移动时更易于维护,直接指针访问则需修改指向。
Java堆内存按照对象的分代年龄划分,分为Young区与Old区。对象首先在Young区生成,达到一定年龄进入Old区。这种分代策略减少了一次完整堆内存扫描的需要,提高了性能。
Young区内存管理过程中,遇到空间不连续问题时,引入Eden区与Survivor区的双区策略,解决了空间不连续引发的GC问题。通过Eden区与Survivor区的循环复制,保证了内存的有效使用。
Old区用于存放分代年龄较高的对象,当Old区满时,触发Full GC。若清理空间仍不足,将抛出OutOfMemeoyError异常。
本文探讨了`new Object()`占用字节的问题,以及Java对象在内存中的布局、内存模型、堆内存分代、空间管理策略等。关于GC及GC算法等知识将在后续文章中深入分析。