(2)本地线程分配缓冲(Thread Local Allocation Buffer, TLAB) : 每个线程在Java堆中预先分配一小块内存,当某线程的TLAB用完后再分配新的TLAB时,才需要同步锁定
3.内存分配完成后,JVM将分配到的内存空间初始化为零值。--- 以保证对象的实例字段可以不赋初始值就能直接使用(这一块没弄懂)
4.对对象进行必要的设置。如对象头中设置对象的哈希码、对象的GC分代年龄、对象是哪个类的实例的标志等
三。对象的内存布局
对象在内存中布局可以分为三块
1.对象头:可分为两部分 :(1) 第一部分用于存储对象自身的运行数据。如哈希码、GC分代年龄、锁状态标志、线程持有的锁等
(2) 第二部分是类型指针,即对象指向它的类元数据的指针。JVM可通过这个指针确定对象是哪个类的实例
但并不是每个JVM都会在对象数据上保留类型指针,因为还有其他方法可以查找对象的元数据。
2.实例数据:对象真正存储的有效信息,即程序代码中定义的各种类型的字段。
如父类继承的、子类重定义的等
3.对齐填充:这部分不是必然存在的。仅仅起着占位符的作用。以HotSpot虚拟机为例,对象起始地址必须是8字节的整数倍,即对象大小必须是8字节的整数倍。
而对象头部分正好是8字节,当实例数据部分没有对齐时,则需要通过对齐填充来补全。
此外,对象的主流访问定位方式有两种:(1)使用句柄:优点:引用中存储的是稳定的句柄地址,句柄中存放对象实例数据指针和对象类型指针,当对象移动时(垃圾回收时的普遍行为),只需改变句柄中的实例数据指针。
(2)直接指针:优点 -- 快,节省时间开销 -- 地址指向的一块内存中既有对象实例数据,也有对象类型数据指针。
使用句柄访问时,会在Java堆中划分出一块内存出来作为 句柄池
即句柄池也在Java堆中。