Ⅰ new Object()到底占用几个字节
Java对象内存布局
Java对象在内存中的布局可以分为三部分:对象头、实例数据和对齐填充。在64位操作系统下,对象头包含Mark Word,大小为8字节,用于存储对象的分代年龄等信息。实例数据包含对象的实际属性,大小取决于具体对象。对齐填充用于确保对象大小是8字节的倍数,大小根据需要决定,可能为空。
创建一个新对象时,如使用`new Object()`,对象占用的字节数取决于是否开启了指针压缩。若未开启,对象占用大小为16字节(8字节Mark Word + 8字节Class Pointer)。若开启指针压缩,Class Pointer被压缩为4字节,最终大小为16字节(8字节Mark Word + 4字节Class Pointer)。实际验证结果证实,无论指针压缩是否开启,new Object()的占用大小都是16字节。
在对象实例中添加属性后,对象占用的字节数会增加。开启指针压缩时,对象占用16字节;关闭指针压缩时,对象占用24字节。
对象访问方式有句柄访问和直接指针访问两种。句柄访问中,对象存储句柄地址,句柄池存储对象实例数据和类型数据地址,减少定位对象的开销。直接指针访问方式下,对象直接存储类型数据。
句柄访问相较于直接指针访问有减少对象移动带来的引用更新操作的优点,但需要额外的句柄池开销。直接指针访问则减少了句柄访问的额外开销,但当对象移动时需要更新引用。
Java堆内存根据对象的分代年龄分为Young区和Old区。Young区包括Eden区和Survivor区,用于存放生命周期较短的对象。Old区存放生命周期较长的对象。当Young区存储满时,会触发垃圾回收(GC)。Eden区存储新对象,Survivor区存储幸存对象。通过连续分配和移动对象,减少空间碎片,提高内存使用效率。
对象的人生轨迹图可以概括为:在Eden区创建,Eden区满时触发GC,幸存对象移动到Survivor区,Eden区清理。当Survivor区满时,幸存对象移动到Old区,Eden区再次清理。当Old区满时,触发Full GC。若空间不足,触发Full GC失败时,抛出OutOfMemoryError异常。
在理解Java对象内存布局的基础上,可以更深入地理解Java垃圾回收(GC)的工作原理和内存管理策略。掌握这些知识对于优化Java程序性能、减少内存泄漏和提高程序稳定性至关重要。