JVM——java虚拟机建立对象与寻址对象

JAVA虚拟机建立对象的流程算法

 

JAVA对象的结构安全

空间分配

空间分配的两种方式

指针碰撞

    当已分配空间被集中存放,已分配和未分配空间使用一个指针来标记时,分配新的空间只须要移动该空间便可,此方法为指针碰撞。适用于GC算法会作COMPACT的状况。线程

空闲列表

    当已分配的空间是分散存放时,虚拟机必须维护一个记录了哪些内存块是可用的列表,此为空闲列表,须要分配新空间时只须要从该列表中获取。指针

解决空间分配线程安全问题的两种方式

CAS方式失败重试

    顾名思义,赶上分配时的线程冲突时,会再次进行空间分配直至成功。实现简单直观可是效率较低对象

空间划分

    为每一个线程分配单独的一块空间,该空间只用来给该线程作建立对象分配空间时使用,这单独的空间被称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。当该线程的TLAB分配光了后,才须要同步锁定,效率较高。是否使用TLAB能够经过虚拟机参数指定。blog

设置对象头(对象管理的必要信息)

  空间初始化成0后(初始化不包含对象头),须要针对对象设置一些必要信息,如:对象归属于哪一个类、对象的hash码、对象的GC分代年龄等,这些信息都放在对象头中。根据虚拟机状态——如是否使用偏向锁,设置对象头。内存

对象头包含信息

    对象头包含两部分信息:同步

      • 运行时数据(hash码、GC分代年两、持有锁、锁标识状态、偏向线程ID),这部分数据被称为Mark Word。
      • 类型指针,用来讲明该对象是哪一个类的实例。

设置对象实例数据

  对象的实例数据主要是根据JAVA代码的编写生成的,包含包括父类在内的各类类型的字段,其字段安排的顺序受虚拟机实现及代码的编写影响。虚拟机

虚拟机安排字段的方式

    一、相同宽度的字段放在一块儿hash

    二、父类的字段放在子类的前面

    三、窄小的变量也会被安排在父类的字段空隙中(C++的内存安排规则,HotSpot VM是由C++语言编写)

填充字段

  HotSpot VM要求对象的其实位置必须是8字节的整数倍,也就是说对象必须是8字节的整数倍,因此须要填充占位(这也是一句C++的规则来的)。

 

对象的定位

  JAVA程序访问对象须要经过栈上的reference数据操做堆上的具体对象。reference对象要么经过指向句柄再指向对象实例,要么直接指向对象实例。

以句柄的方式访问

    使用句柄方式访问对象实例,须要在堆中划分出一起句柄池,句柄与指针相似,记录了具体的实例所存放的地址。这种方式的好处是reference是稳定的,当对象实例地址改变时,只需改变句柄中的对象实例指针。

 

以指针直接访问

    以指针方式访问对象实例,是经过reference直接指向对象实例,优势是速度快,由于比句柄访问方式少了一次寻址的过程。

 

PS:对象实例数据指的是具体的对象,对象类型对象指的是该实例数据对象所属的Class类对象。

相关文章
相关标签/搜索