JAVA对象的实例化内存布局与访问定位刨析

本文详细剖析了JAVA对象的实例化过程,包括创建对象的方式、步骤,对象的内存布局和访问定位。讨论了类加载、内存分配、并发安全问题、对象头、实例数据、对齐填充以及句柄访问和指针访问的机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. 创建对象的方式

1.1 创建对象方式具体描述

2. 创建对象的步骤

2.1 判断对象对应的类是否加载、链接及初始化

2.2 为对象分配内存

2.3 处理并发安全问题

2.4 初始化分配到空间

2.5 设置对象的对象头

2.6 执行init()方法进行初始化

3. 对象的内存布局

3.1 对象头

3.2 实例数据

3.3 对齐填充

4. 对象的访问定位

4.1 使用句柄访问

4.2 使用指针访问

1. 创建对象的方式

         创建对象的方式有多种,例如使用new关键字、Class的newInstance()方法、Constructor类的newInstance()方法、clone()方法、反序列化、第三方库Objenesis等,如图所示。

 

1.1 创建对象方式具体描述

      ①使用new关键字——调用无参或有参构造器创建。
      ②使用Class的newInstance()方法——调用无参构造器创建,且需要是public的构造器。
      ③使用Constructor类的newInstance()方法——调用无参或有参、不同权限修饰构造器创建,实用性更广。
     ④使用clone()方法——不调用任何参构造器,且对象需要实现Cloneable接口并实现其定义的clone()方法,且默认为浅复制。
     ⑤使用反序列化——从指定的文件或网络中,获取二进制流,反序列化为内存中的对象。
第三方库Objenesis——利用了asm字节码技术,动态生成Constructor对象。

2. 创建对象的步骤

2.1 判断对象对应的类是否加载、链接及初始化

       虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化(即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以“ClassLoader+包名+类名”为Key查找对应的“.class”文件。如果没有找到文件,则抛出ClassNotFoundException异常。如果找到,则进行类加载,并生成对应的Class类对象。如下图所示,

2.2 为对象分配内存

       首先计算对象占用空间大小,接着在堆中划分一块内存给新对象。如果实例成员变量是引用变量,仅

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10年JAVA大数据技术研究者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值