深入理解java虚拟机-java对象创建(2)

java对象的创建

首先当jvm遇到一个new指令的时候,是否能在方法区查找到这个类的符号引用,并检查是否加载,如果没加载,则进行类加载,链接,初始化当前类。

假如有多个线程进行对象的创建,比如线程1,为对象A分配了一个地址X,还没来得及吧地址X赋值给A,

这个时候线程2为对象B分配地址X那么就出现线程安全问题,JVM是通过CAS保证分配的原子性,或者通过 

 

 

TLAB(Thread local allocation buffer)为线程在堆中分配私有的线程缓冲,当TLAB用完再去使用CAS分配。

开启 TLAB -XX:+UseTLAB (默认);关闭-XX:-UseTLAB

这个时候就已经在堆中分配了内存空间,初始化为零值,虚拟机还需要对这个对象的对象头进行设置,比如类元数据,hash值,GC年龄等;

 

补位是因为Hotspot的内存管理必须是8字节的整数倍。

对象头中使用的是非固定的数据结构,即mark work

在32位的虚拟机中mark work如下,这样设计是为了在有限的空间内存储更多的数据

 

01标志位,hash码值的是当前对象的引用地址,和当前对象的存活的年纪(每monitor gc一次,年纪加1)

00标志位,当进入同步块的时候,如果没有被锁定,那么线程在当前线程栈中创建一个 lock record的空间,并且通过CAS,把对象的头中指针更改为当前lock record的指针,并且更新标志位为00

10标志位,如果上面的操作失败了,锁就要膨胀为重量级锁了锁标志的状态,指针就是重量级指针,后面的线程将阻塞

01标志位,偏向锁,实际上是和上面的一样但是还有一位0/1来区分是否可偏向

偏向位0表示不可偏向,即最上面的01标志位,偏向位1表示可以偏向,即偏向锁

 

 

对象的访问定位:

可以通过句柄池来定位对象,也可以使用直接指针(Hotspot采用这个)

通过句柄定位的优势是,当进行对象移动的时候,只需要改变句柄中实例的地址就行。

直接指针的优势是,少了一层中间句柄的开销

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值