对象的创建与访问

对象的创建

虚拟机遇到new指令后,首先检查这个指令的参数是否能在常量池定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被,加载,解析和初始化过,如果没有,那必须执行相应的类加载过程。在类加载检查通过后,虚拟机将为新生对象分配内存,对象所需内存的大小在类加载后便可以确定,为对象分配空间的任务等同于把一块确定大小的内存从java堆中划分出来。

对象内存分配的方式
指针碰撞

假设Java堆是规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点,分配内存就等同于把指针向空闲空间那边挪动一段与对象相等的距离,这种分配方式称为指针碰撞

空闲列表

假设Java堆不是规整的,已使用的内存和空闲的内存相互交错,虚拟机维护一个列表,记录哪些块是可用的,在分配的时候从列表找到一块足够大的空间划分给对象,并更新列表的记录,这种方式称为空闲列表

对象信息的设置

内存分配完成后,虚拟机还需要对对象进行必要的设置,比如这个对象是那个类的实例,如何能找类的元数据信息,对象的哈希吗,对象GC分代年龄等信息,这些信息存放在对象头之中。

Init初始化

在上面的工作都完成后,从虚拟机的角度来讲,一个新的对象已经产生,但从Java程序的视角来看,对象的创建才刚刚开始,还需要执行init方法对对象进行初始化。

对象的内存布局

对象在内存布局可以分为三个部分:对象头,实例数据,对齐填充
对象头存储的数据分为两部分,一个部分为对象自身的运行数据,如hash值,GC年龄和锁标志,一部分为类型指针,即对象指向它的类元数据指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
实例数据部分是对象真正存储的有效信息,是在程序代码中所定义的各种类型的字段内容
对齐填充没有特别的含义,就是起一个占位符的作用

对象的访问定位

句柄访问:java堆划分出一块内存来作为句柄池,栈中的reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息
图片来源:深入理解jvm虚拟机
直接指针访问::java堆对象的布局中必须考虑如何放置访问类型数据的相关信息,而reference中存储的直接就是对象地址
图片来源:深入理解jvm虚拟机

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值