对jvm的学习—对象创建

对空间的分配,虚拟机采用的两种方式保证原子性

CAS加失败重试的方式

CAS compare and swap 先比较再交换,比较原值是否一直来保证原子性。

失败重试就会再次调用新的值再来重试

本地线程分配缓存(TLAP Thread Local Allocation Buffer)

每个线程都会在内存空间预先分配一小块内存。虚拟机将分配的内存地址都置零,这样类对象的实例字段在java中就可以不负初值就可以直接使用,程序可以直接访问到所属数据类型的零值。

对象的内存布局

对象头(header)

对象头部分包括两类信息。

第一类是用于存储对象自身的运行时数据,如哈 希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,称为“Mark Word”;

对象头的另外一部分是类型指针,即对象指向它的类型元数据的指针。

如果对象是个数组还有一块用于记录数组长度的数据(数组的长度是一种属性,而非方法)

实例数据(Instance Data)

对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字 段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。

对齐填充(Padding)

这并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作 用。由于HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是 任何对象的大小都必须是8字节的整数倍。对象头部分已经被精心设计成正好是8字节的倍数(1倍或者 2倍),因此,如果对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。

对象的访问定位

句柄

Java堆中将可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息。

优点:reference中存储的是稳定句柄地 址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而 reference本身不需要被修改

直接指针

Java堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销。

优点:是速度更快,它节省了一次指针定位的时间开销。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值