深入理解java虚拟机学习-2

文章详细阐述了在JVM视角下对象的创建过程,包括类的加载检查、内存分配和对象初始化。接着讨论了对象在堆内存中的布局,分为对象头、实例数据和对齐填充三部分。对象头包含运行时数据和类型指针,实例数据存储字段内容。最后,提到了对象的访问定位,主要通过句柄或直接指针两种方式实现。
摘要由CSDN通过智能技术生成

jvm 虚拟机对象

对象的创建

在这里插入图片描述
在jvm视角中,java创建如图所示,主要步骤如下:

  1. java虚拟机遇到一个字节码new的指令时,首先将会去检查这个指令的参数是否能够在常量池中定位一个类的符号引用,并检查这个符号引用代表的类是否已经加载,解析和初始化过。如果没有需要走类的加载过程。
  2. 类加载检查后,虚拟机将为新生的对象分配内存,即从java推中划分一块内存。
  3. 初始化内存空间,除了对象头,其他的空间默认初始化为0.
  4. 对对象做一些必要的设置,如对象时哪个类的实例,如何才能找到类的元数据信息。

对象的内存布局

对象在堆内存中的存储布局可以划分为三个部分: 对象头(Header), 实例数据(Instance Data)和对齐填充(Padding)。

  1. 对象头包括两部分信息, 第一类,存储对象自身运行时数据,如哈希码,GC分代年龄,锁状态标志,线程持有锁,偏向线程ID,偏向时间戳等。这一部分数据长度在32位和64位虚拟机中分别为32个比特和64个比特,通常他被称为“Mark Word”。
    在这里插入图片描述
  2. 对象头另一部分便是类型指针,即指向它的类型元数据的指针,java虚拟机通过这个指针来确定该对象是哪个类的实例。 此外,如果对象是一个java数据,还需要在对象头中记录数据的长度数据。
  3. 在实例数据部分存放的是对象真正存储的有效信息。 这部分数据包括我们在程序代码中所定义的各种类型字段内容,包括父类继承下来的,或是在子类中定义的字段.通常来说,父类定义的变量一般都会早于子类之前。
  4. 最后是对齐填充,这并不是必然存在,主要是HotSpot虚拟机中要求对象起始地址必须是8的整数倍。所以所有的对象都会被补齐到这个地址。当然如果前面的数据在填充完毕后正好是8字节的倍数,这部分是不需要填充的。

对象的访问定位

在对象创建完成之后,java程序会通过栈上的reference(指针/引用)数据来操作堆上的具体对象。指针一般用于指向具体对象,但如何实现,一般不同的java虚拟机实现不太一样,主要有以下两种方式:

  1. 使用句柄访问,java划分堆一块区域为句柄池,句柄里保存了到对象实列数据的指针和到对象类型数据的指针。优势是,对象移动后只需要改变句柄的地址即可,指针本身的地址不需要改变。
  2. 使用直接指针,可以直接访问到对象,但对象需要存放对象的类型数据的指针。之访问对象本身,是只需要访问一次即可。优势是,直接访问对象数快。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值