jvm中对象是怎么存储的,对象的内存布局是怎样的

对象通过new,反射,clone等方式创建完毕后被存储到堆中,那么对象是以什么样的方式存储在堆中的?

对象的内存布局

对象在堆内存的内存布局主要有三部分,即对象头,实例数据,对其填充

对象头

对象头主要包含两部分的内容,一个叫运行时元数据(mark word),一个叫类型指针

  • 1.运行时元数据
    • 哈希值(hashcode):对象在堆空间中都有一个首地址值,栈空间的引用根据这个地址指向堆中的对象,这就是哈希值起的作用
    • GC分代年龄:对象首先是在Eden中创建的,在经过多次GC后,如果没有被进行回收,就会在survivor中来回移动,其对应的年龄计数器会发生变化,达到阈值后会进入养老区
    • 锁状态标志,在同步中判断该对象是否是锁
    • 线程持有的锁
    • 线程偏向ID
    • 偏向时间戳
  • 2.类型指针,指向元数据区的代表当前类的class对象,确定该对象所属的类型

说明:如果对象是数组,则还需要记录数组的长度

实例数据(Instance Data)

它是对象真正存储的有效信息,包括程序代码中定义的各种字段类型(包括从父类继承下来的和自己本身拥有的字段),注意这里有一些规则:相同宽度的字段总是被分配在一起,父类中定义的变量会出现在子类之前,因为父类的加载是优先于子类加载的

对齐填充

没有特殊含义,仅仅起到占位符的作用

小结

现在有一个Customer cust = new Custome()的对象,通过上面的叙述,我们通过一张图来直观的了解下:

在这里插入图片描述

补充:对象访问方式

在创建好对象后,通过栈帧上的引用访问堆中的实例,这种访问方式可以分为两种方式:句柄访问和直接指针(HotSpot采用)

句柄访问:

在这里插入图片描述

直接指针:

和我们介绍内存布局是一样的
在这里插入图片描述
两种方式比较:
直接指针效率往往比句柄访问高,且不需要专门维护句柄池,内存花费小,当对象实例发生移动时,通过指针访问的引用也要发生变化,而句柄方式的reference则不需要改变

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值