二、对象的创建过程、对象信息、对象访问方式

一.对象创建流程

1.当遇到new指令时,检查是否能在常量池定位到一个类的符号引用,检查这个符号引用代表的类是否已被加载、解析、初始化过。若没有,将执行类的加载过程。
2.为对象分配内存。分配多大在类加载完成后就已得知。

  • 分配方式
  • 指针碰撞:假设java堆上内存规整,一边是空闲的内存,一边是已使用过的内存。那么分配内存的操作就是,把指针向空闲内存的方向移动一段与对象大小的距离。
    在这里插入图片描述
  • 空闲列表:维护一个记录可用内存块的表,在分配时寻找一块足够大的空间给对象实例,并更新记录。

解决并发情况下线程不安全的情况:

  • 内存分配:虚拟机采用CAS(比较交换)+失败重试的机制保证更新操作的原子性
  • TLAB:为每个线程在Java堆上分配一个一小块区域当做缓冲区,只有这个缓冲区用完时,分配新的缓冲区时才进行同步锁定

3.将分配到的空间(不包括对象头)初始化为零值(使用了TLAB,这步会在TLAB分配时进行)。这步使对象实例字段在Java代码中可以不赋初始值就可以直接使用。
4.对对象进行设置,如对象是哪个类、哈希码、GC分代年龄等。这些信息都在对象头中。

二、对象信息

对象信息由三部分组成:对象头、实例数据、对齐填充。

对象头

对象头中含两类信息:

  • 第一类:用于存储对象自身的运行时数据:如哈希码、GC分代年龄、锁状态标志、持有的锁、偏向时间戳、偏向线程ID等。
  • 第二类:类型指针,指向对象的类型元数据指针-----类。但是虚拟机实现不一定都会在对象类型保留类型指针。即查找对象元数据信息不一定通过对象本身。

实例数据

存储父类继承下来的和子类中定义的字段

对齐填充

非必然,使对象大小为8字节的整数倍。

三、对象的访问定位

Java程序会通过栈上的reference类型数据操作堆上的数据。目前有两种主流的实现方式。

句柄访问

Java堆会分配一块内存存作为句柄池存放句柄,对象移动时(垃圾收集普遍发生),reference(存储句柄地址)不改变,只改变句柄存放的内容。
在这里插入图片描述

直接指针

reference直接存储对象地址,好处是节省一次指针定位的时间开销。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值