本文的主要问题如下:
问题:new Object() 在内存中占用多少字节?
对象的结构
Hotspot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
- 对象头:比如 hash 码,对象所属的年代,对象锁,锁状态标志,偏向锁(线程)ID,偏向时间,数组长度(数组对象才有)等。
- 实例数据:存放类的属性数据信息,包括父类的属性信息;
- 对齐填充:由于虚拟机要求 对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐。
对象头详解
HotSpot虚拟机的对象头包括:
- Mark Word
用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机中分别为 32bit 和 64bit,官方称它为 “Mark Word”。 也就是说32位虚拟机4字节,64位虚拟机8字节。
Mark Word 中具体存的是什么呢?我们可以看下面这一张表(以 64 位操作系统为例,这里暂不展开):
- Klass Pointer
对象头的另外一部分是klass类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。 32位4字节,64位开启指针压缩或最大堆内存<32g时4字节,否则8字节。jdk1.8默认开启指针压缩后为4字节,当在JVM参数中关闭指针压缩(-XX:-UseCompressedOops)后,长度为8字节。
- 数组长度(只有数组对象有)
如果对象是一个数组, 那在对象头中还必须有一块数据用于记录数组长度。 长度为4字节。
正确答案
在 JDK8 下 64位操作系统中 new Object() 占多少字节?
答案:16 字节
8 个字节是 MarkWord
4 个字节是指针(jdk 8 默认开启指针压缩) 4 个字节是对齐填充位
动手实践一下
jol 插件可以打印对象布局,首先我们加入依赖:
implementation 'org.openjdk.jol:jol-core:0.9'
测试代码 ```java public class NewObjectLayoutTest {
public static void main(String[] args) {
System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());
} }
1. 输出结果
```java
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
总结
大家 get 到了吗?理论是实践的基础,欢迎留言。
参考
作者:心城以北
链接:https://juejin.cn/post/7101658548232257549
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。