对象的创建和访问

一、对象的组成:

JVM堆上的对象主要由三部分组成:对象头、对象实例数据和对齐填充。

对象头:对象头主要由两部分组成,对象运行时的数据和指向对象所属类信息的指针。数组对象还包含一个数组长度信息。

对象运行时的数据主要包含对象的hashcode 25b,GC 分代年龄4位,锁状态标志,线程持有的锁,偏向线程ID,偏向线程时间戳等。

通过句柄访问对象指向对象所属类信息的指针为空。

对象的实例数据是指类生命的实例变量部分。

因为Hotspot虚拟机堆的基本单位是字节,所以要求对象的大小是8的倍数。因此需要对其填充

二、对象的创建:

当虚拟机遇到一条new指令时,回首先判断该指令操作的符号引用所表示的类有没有加载到内存中,没有则首先进行类的加载、验证、准备、解析、初始化过程,然后检查该类的访问权限,在检查通过后,则需要在堆上划分一块区域供该对象使用,若堆是干净整洁的,已使用的在一端,未使用的在另一端,则使用指针碰撞的方式为对象分配一块区域,否则,虚拟机将维护一张表叫”空闲列表“,检查表中是否有足够大的条目供对象使用。具体使用哪种方式跟具体的垃圾收集算法有关。为了保持在并发环境下的安全,JVM采用CAS+重试的方式进行对象分配,为了提高分配的效率,JVM在创建线程时会预先分配一块较小的内存共线程使用,称为本地线程分配缓存(TLAB)。内存分配完毕后,会对该内存进行初始化操作(清零)。

三、对象的访问:

JVM访问对象的方式主要有两种:句柄访问和直接引用。

句柄访问:虚拟机在堆中维护一个句柄列表,句柄中主要包含两部分:类的元数据对象地址和类的实例对象地址。每次访问一个对象时,先访问该对象的句柄,再通过句柄访问对象在堆上的实例。这样带来的好处就是引用类型的值是稳定的,假如对象发生了变化,只需要在句柄中修改即可。

对象的创建和访问

直接引用:JVM直接访问对象在堆上的实例地址,再通过堆上的实例中的对象头访问对象的元数据信息。相比句柄访问的好处引用指向的就是对象的实际位置,无需再次访问。

对象的创建和访问