java 中的对象_JAVA中对象

对象内存布局(HotSpot)

概述

布局划分为三部分:对象头(Header)、实例数据(Instance)、对齐填充(Padding)

对象头包含两类信息:用于存储对象自身的运行时数据(Mark Word)和对象指向它的类型元数据的指针(类型指针)

实例数据部分时对象真正存储的有效信息,存储顺序受JVM分配策略参数和字段在java源码中定义顺序的影响,

HotSpot默认存储顺序:long/double,int,short,char,byte/boolean,oop(Ordinary Object Pointer)

对齐填充部分不是必须存在,也没有任何含义,仅仅用于占位符

对象头(Header)

对象自身的运行时数据(Mark Word)

这部分数据的长度在32位和64位的未开启压缩指针的JVM中分别为32bit和64bit。

Mark Word是一个有着动态定义的数据结构,目的在于在极小的空间存储更多的数据,根据对象的状态复用自己的存储空间

32位HotSpot中,如果对象未被同步锁锁定的状态下,Mark Word的32bit存储空间中,25bit用于存储对象哈希码,4bit存储对象分代年龄,2bit存储锁标志位,1bit固定为0。其他状态存储内容如下表

锁状态25bit4bit1bit2bit

23bit2bit是否偏向锁锁标志位

无锁对象的HashCode分代年龄001

偏向锁线程IDEpoch分代年龄101

轻量级锁指向栈中锁记录的指针00

重量级锁指向重量级锁的指针10

GC标记空11

类型指针

JVM通过这个指针来确定该对象是哪个类型的实例

并不是所有JVM实现都必须在对象数据上保留类型指针。

如果对象是数组,对象头中还必须有一块用于记录数组长度的数据

New对象()

JVM创建对象过程

8d2d898ae7bf5bf8ef71a2ac39b000b9.png

对象查找

概述

reference类型在JVM规范中只规定了它是一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置

主流访问方式有:使用句柄和直接指针

通过句柄访问

JVM将在队中划分除一块内存作为句柄池,reference中存储对象的句柄地址,而句柄包含了对象实例和类型数据各自的地址信息

优势是:reference存储的是稳定句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而本身不用被修改

8e3a67e240e197c3fd7b8c88de303385.png

通过直接指针访问

堆中的内存布局必须考虑如何放置访问类型数据的相关信息,reference存储的就是对象地址

访问对象本身,不需要多一次间接访问开销,相对句柄,速度块,节省了一次指针定位的时间开销

Hotspot主要使用此方法访问

08d51f982b24258f0ac13334232556d5.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值