这篇文章,我们来了解一下对象在内存中的布局是什么样的。
解释:前面有一篇文章我们讲了JVM中类的结构,那里讲的是一个java类,被编译成二进制字节码后,它的结构是什么样的,或者说按照jvm的标准,一个.class文件中类的结构是什么样的。而这里我们要讲的是根据类在堆中创建出来的对象,它在堆中是如何布局,即它在堆中的结构是怎样的。一个是微观的,类层次的,一个是宏观的,对象层次的。这个对象的更底层源码,肯定也是按照java类的结构布局的。
对象的内存布局:一个对象的内容可以分为三大部分,对象头、示例数据、对象填充
对象头(Header)
包含两部分
- 运行时元数据
- 哈希值( HashCode )
- GC分代年龄
- 锁状态标志
- 线程持有的锁
- 偏向线程ID
- 偏向时间戳
- 类型指针:指向类元数据的InstanceClass,确定该对象所属的类型
说明:如果是数组,还需记录数组的长度
实例数据(Instance Data)
说明:它是对象真正存储的有效信息,包括程序代码中定义的各种类型的字段(包括从父类继承下来的和本身拥有的字段) 规则:
- 相同宽度的字段总被分配在一起
- 父类中定义的变量会出现在子类之前
- 如果CompactFields参数为true(默认为true),子类的窄变量可能插入到父类变量的空隙
对齐填充(Padding)
不是必须的,也没特别含义,仅仅起到占位符作用
图示小结