HotSpot VM 中,对象在堆内存中的存储布局分为:
对象头(Header)
实例数据(Instance Data)
对齐填充(Padding)
1、对象头
Mark Word,对象运行时数据,动态定义位数据。包含 HashCode、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等。32 位和 64 位的 VM 里 Mark Word 的长度分别 32 bit 和 64 bit。
类型指针,对象指向所属 class 的元数据的指针,32 位 VM 4 byte,64 位 VM 8 byte(-XX:+UseCompressedOops 压缩指针 4 byte)。非必需,取决 JVM 实现。
数组对象必须包含长度信息,4 byte。
2、实例数据
按分配策略和源码定义的顺序,存储对象的字段数据。
8 byte:long、double
4 byte:int、float、oops(Ordinary Object Pointers)
2 byte:short、char
1 byte:byte
1 bit:boolean
3、对齐填充
非必需,保证对象大小是 8 字节的整数倍进行填充的长度。
没有特殊含义,仅占位。
new 语法创建普通 Java 对象的过程
检查类是否已加载、解析、初始化,若没有则进行。
为新对象分配内存。规整的内存使用指针碰撞(Bump The Pointer);不规整的内存使用列表记录可用内存的方式配分叫空闲列表(Free List)。
配分内存的两种安全方式:CAS;每个线程在 Heap 中预先分配一小块内存,即本地线程分配缓存(Thread Local Allocation Buffer)。
初始化分配的内存,字段设为默认零值
根据 JVM 运行的情况,设置对象头信息。如类的元数据、HashCode、GC 分代年龄、偏向锁...
执行构造函数、字段赋值...
通过栈上的 reference 数据定位、访问堆上的对象,两种方式:
句柄访问。栈中本地变量表里的 reference 存储的是堆中句柄池中对象的句柄地址,句柄包含了对象实例数据和类型数据的地址。
直接指针。栈中本地变量表里的 reference 存储的是对象数据地址,可以直接访问,少一次寻址访问速度快。
ConstXiong 备案号:苏ICP备16009629号-3