JAVA虚拟机建立对象的流程算法
JAVA对象的结构安全
当已分配空间被集中存放,已分配和未分配空间使用一个指针来标记时,分配新的空间只须要移动该空间便可,此方法为指针碰撞。适用于GC算法会作COMPACT的状况。线程
当已分配的空间是分散存放时,虚拟机必须维护一个记录了哪些内存块是可用的列表,此为空闲列表,须要分配新空间时只须要从该列表中获取。指针
顾名思义,赶上分配时的线程冲突时,会再次进行空间分配直至成功。实现简单直观可是效率较低对象
为每一个线程分配单独的一块空间,该空间只用来给该线程作建立对象分配空间时使用,这单独的空间被称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。当该线程的TLAB分配光了后,才须要同步锁定,效率较高。是否使用TLAB能够经过虚拟机参数指定。blog
空间初始化成0后(初始化不包含对象头),须要针对对象设置一些必要信息,如:对象归属于哪一个类、对象的hash码、对象的GC分代年龄等,这些信息都放在对象头中。根据虚拟机状态——如是否使用偏向锁,设置对象头。内存
对象头包含两部分信息:同步
对象的实例数据主要是根据JAVA代码的编写生成的,包含包括父类在内的各类类型的字段,其字段安排的顺序受虚拟机实现及代码的编写影响。虚拟机
一、相同宽度的字段放在一块儿hash
二、父类的字段放在子类的前面
三、窄小的变量也会被安排在父类的字段空隙中(C++的内存安排规则,HotSpot VM是由C++语言编写)
HotSpot VM要求对象的其实位置必须是8字节的整数倍,也就是说对象必须是8字节的整数倍,因此须要填充占位(这也是一句C++的规则来的)。
JAVA程序访问对象须要经过栈上的reference数据操做堆上的具体对象。reference对象要么经过指向句柄再指向对象实例,要么直接指向对象实例。
使用句柄方式访问对象实例,须要在堆中划分出一起句柄池,句柄与指针相似,记录了具体的实例所存放的地址。这种方式的好处是reference是稳定的,当对象实例地址改变时,只需改变句柄中的对象实例指针。
以指针方式访问对象实例,是经过reference直接指向对象实例,优势是速度快,由于比句柄访问方式少了一次寻址的过程。
PS:对象实例数据指的是具体的对象,对象类型对象指的是该实例数据对象所属的Class类对象。