【Java虚拟机】2.HotSpot虚拟机对象管理

对象的创建

当Java虚拟机遇到一条new字节码指令时,首先检查指令的参数是否在常量池中能够定位到,并且检查这个符号引用代表的类是否已经被加载、解析、初始化过,如果没有那就必须先执行相应的类加载过程。

接下来会给新生的对象分配空间,分配策略根据是否带有空间压缩整理功能分为两种:

  • 指针碰撞
    空闲的区域是连续的,用一个指针来确定空闲与非空闲的边界
  • 空闲列表
    空闲的区域不是连续的,维护一个列表来确定空闲区域的位置

同时由于新对象的创建是一个非常频繁的操作,需要解决并发问题,解决办法也有两个:

  • 进程共享内存空间,采用CAS配上失败重试的策略保证操作的原子性
  • 把内存分配的动作按线程划分在不同的空间中进行,每个线程拥有一小块独立的内存叫做本地线程分配缓冲(Thread Local Allocation Buffer TLAB)

内存分配结束之后需要讲分配到的内存空间(不包括对象头)都初始化为零,然后对对象进行必要的设置,也就是初始化对象头(包括这个对象是哪个类的实例、如何才能找到类的元信息、对象的哈希码、对象的GC分代年龄信息等)。然后再开始执行对象的构造函数,给属性赋值。

对象的内存布局

对象在堆内存中分为三个部分:对象头、实例数据和对齐填充。

对象头

对象头有两个部分组成:Mark Word和类型指针。
Mark Word根据标志位的标志不同会代表不同的内容:
image
其中在轻量级锁定以及重量级锁定的时候,在上锁之前会把对象头中的Mark Word复制一份到另一块内存区域进行存储。
类型指针即对象指向它类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例。如果该对象还是一个数组,拿在对象头中还必须有一块用于标记数组长度的数据。

实例数据

HotSpot虚拟机默认的分配顺序为longs/doubles、ints、shorts/chars、bytes/booleans、oops(Ordinart Object Pointers)相同宽度的字段总是被分配到一起存放,在满足这个前提下,在父类中定义的变量会出现在子类前。

对齐补充

用于占位使对象大小成为8字节的倍数

对象的访问定位

主流的方式有两种:

  • 句柄访问,好处是对象移动或者删除之后不需要改变本地变量表中的指针,坏处是会多一步寻址的开销
    image

  • 直接指针,好处是减少寻址的开销,坏处是需要更改本地变量表的指针
    image

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值