对象的内存布局
平时用java编写程序,你了解java对象的内存布局么?
在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:
- 对象头
- 实例数据
- 对齐填充
对象头
对象头包括两部分信息:
MarkWord
第一部分用于存储对象 自身 的 运行时数据 ,如:
- 哈希码(HashCode)
- GC分代年龄
- 锁状态标志
- 线程持有的锁
- 偏向线程ID
- 偏向时间戳
这部分数据的长度在32和64位虚拟机中分别为32bit和64bit,官方的名称是 “MarkWord”。
Mark Word被设计成一个非固定的数据结构以便在极小的空间内储存尽量多的信息,它可以根据对象的状态复用自己的存储的空间。
存储内容 | 标志位 | 状态 |
---|---|---|
对象哈希码、对象分代年龄 | 01 | 未锁定 |
指向记录的指针 | 00 | 轻量级锁定 |
指向重量级锁的指针 | 10 | 膨胀(重量级锁定) |
空,不需要记录信息 | 11 | GC标记 |
偏向线程ID、偏向时间戳、对象分代年龄 | 01 | 可偏向 |
类型指针:指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
并不是所有的虚拟机都必须实现在对象数据上保存类型指针,就是确定对象的元数据不一定经过对象本身。
实例数据
实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段的字段内容。无论是从父类继承下来的,还是在子类中的定义的,都需要记录起来。这部分的存储顺序会收到虚拟机分配策略参数和字段在Java源码中的定义顺序的影响。
对齐填充
你懂得。。。。
占位符,对象起始地址是8字节的整数倍~