当前位置: 首页 > news >正文

对象实例化内存布局与访问定位

对象实例化内存布局与访问定位

  • 对象实例化内存布局与访问定位
    • 对象实例化
      • 创建对象的方式
      • 创建对象步骤
      • 对象内存分布
        • 对象头
        • 实例数据(Instance Data)
        • 对齐填充(Padding)
    • 访问定位
      • 句柄访问(Handle)
      • 直接指针访问(Direct Pointer)

对象实例化内存布局与访问定位

对象实例化

创建对象的方式

  1. 使用new关键字 (调用无参或者有参构造器创建)
  2. Class的newInstance方法(调用的是无参构造器,而且必须是Public修饰的构造器)
  3. Constructor类的newInstance方法
  4. clone方法,不调用构造器,对象需要实现Cloneable接口,默认为浅复制1
  5. 反序列化
  6. 三方库利用asm字节码技术2,动态生成对象2

创建对象步骤

  1. 判断对象对应的类是否加载 链接 初始化
    当虚拟机需要创建对象的时候,首先判断这个创建对象的指令的参数,能不能在常量池中找到对应的类的符号引用,并检查符号引用所代表的类是不是已经被加载 解析 初始化;如果没有,使用双亲委派模式,以ClassLoader 和报名+类名为key查找对应的class文件;如果找不到对应的class文件,抛出异常;如果找到,就将class文件加载到内存,生成Class类对象。

  2. 分配内存

3.处理并发问题
创建对象是比较频繁的操作,如何保证创建新对象的线程安全性?有两种解决方式

  • CAS
  • TLAB
  1. 初始化内存空间
    内存分配结束之后,申请到的空间的值不是固定的,所以拿到内存空间之后,还需要初始化内存空间,这一步将分配到的空间都初始化为0

  2. 设置对象头
    JVM将对象所属类 对象的hashcode 对象的GC信息 锁信息这些数据 写入对象头

  3. 执行init方法初始化
    这一步才是我们写Java代码感知到的初始化,也就是构造器。这一步开始初始化成员变量,执行实例代码块,调用构造器等等

对象内存分布

Java 对象在内存中通常由三部分组成(按顺序排列):

  • 对象头(Object Header)

  • 实例数据(Instance Data)

  • 对齐填充(Padding)
    在这里插入图片描述

对象头
  1. Mark Word
  • 作用:存储对象自身的运行时数据

  • 大小:32 位 JVM:4 字节;64 位 JVM:8 字节(开启指针压缩时为 4 字节)
    在这里插入图片描述

  • unused:未使用的区域。

  • identity_hashcode:对象最原始的哈希值,就算重写hashcode()也不会改变。

  • age:对象年龄。

  • biased_lock:是否偏向锁。

  • lock:锁标记位。

  • ThreadID:持有锁资源的线程ID。

  • epoch:偏向锁时间戳。

  • ptr_to_lock_record:指向线程栈中lock_record的指针。

  • ptr_to_heavyweight_monitor:指向堆中monitor对象的指针。

  1. Klass Pointer(类型指针)

  2. 数组长度(仅数组对象需要)

实例数据(Instance Data)

存储对象的所有字段值,排列顺序受以下规则影响:

  1. 基本类型优先:按 long/double → int/float → short/char → byte/boolean 的顺序

  2. 引用类型最后:所有引用类型(如 String, Object)放在末尾

  3. 父类字段优先:父类的字段出现在子类之前

  4. 紧凑排列策略:-XX:CompactFields=true(默认)允许子类窄字段插入父类空隙

对齐填充(Padding)
  • 作用:确保对象总大小是 8 字节的倍数

  • 原因:CPU 按块访问内存(通常 64 位系统按 8 字节对齐),对齐可提升访问效率

  • 规则:对象头 + 实例数据 的总大小不是 8 的倍数时自动填充

访问定位

句柄访问(Handle)

栈中的引用
句柄池地址
句柄结构
实例数据指针
类型数据指针
堆中对象实例数据
方法区类元数据

工作流程

  • 栈帧中的引用变量存储句柄池地址

  • 通过句柄池地址找到句柄结构

  • 句柄包含两个指针:

    • 实例数据指针 → 指向堆中对象实例

    • 类型数据指针 → 指向方法区类元数据

  • 通过实例数据指针访问对象字段

优缺点

  • 优点:对象移动安全:GC 移动对象时只需更新句柄中的实例指针,栈中引用不变;引用稳定:适合频繁移动对象的 GC 算法(如标记-整理)

  • 缺点:性能损耗:每次访问需两次指针跳转(额外内存访问);内存占用:句柄池消耗额外内存(通常 4-8 字节/对象)

直接指针访问(Direct Pointer)

栈中的引用
堆中对象地址
对象头
类型指针
方法区类元数据
实例字段数据

工作流程

  • 栈帧中的引用变量直接存储堆内存地址

  • 通过地址直接访问对象头

  • 对象头中的 Klass Pointer 指向方法区类元数据

  • 直接访问对象字段数据

优缺点

  • 优点:访问速度快:减少一次内存寻址(性能提升 20-30%);内存紧凑:无句柄池开销,减少内存碎片

  • 缺点:GC 复杂性:移动对象时需更新所有引用(需遍历栈、寄存器等);依赖优化:需要高效的 GC 算法(如复制算法+卡表)


  1. 引用类型的属性(如对象、数组),浅复制仅复制指向该子对象/数组的内存地址(引用),而不是在内存中创建一个全新的副本;对于基本数据类型,浅复制会直接复制值本身。 ↩︎

  2. 一个强大而底层的 Java 库,用于直接操作 Java 字节码(.class 文件) ↩︎ ↩︎

相关文章:

  • weex做的网站世界杯球队最新排名
  • 电商网站合作域名网站
  • 成人在色线视频在线观看免费大全青岛seo推广专员
  • 做网站排名需要多少钱什么是seo是什么意思
  • 莒县城乡建设局网站营销网络是什么意思
  • 用系统建购物网站seo是怎么优化上去
  • spring项目启动sheel脚本
  • SpringBoot 数据库连接池与 ManticoreSearch 兼容性测试
  • 本地如何安装midscene.js运行环境
  • Liunx操作系统笔记2
  • 【AI论文】从跨领域视角重新审视强化学习在大型语言模型推理中的应用
  • 【实时Linux实战系列】基于实时Linux的音频处理应用开发
  • BGP边界网关协议
  • 深度图聚类DGC—Paper Notes
  • Windows所有系统自带.NET Framework版本win7,win10,win11预装.NET版本
  • CommunityToolkit.Mvvm 重构激光直写控制软件
  • Jenkins 常用定时构建脚本
  • 电商导购app平台的缓存策略与性能优化方案:架构师的实践经验
  • 将Python Tkinter程序转换为手机可运行的Web应用 - 详细教程
  • 激光束修复手机屏任意层不良区域,实现液晶线路激光修复原理
  • wordpress Contact Form 7表单插件设置使用教程
  • Hoare逻辑与分离逻辑:从程序验证到内存推理的演进
  • 智能光学计算成像技术与应用
  • 鸿蒙Next仓颉开发语言中的数据类型总结分享
  • 初识Tomcat
  • 6、做中学 | 三年级下期 Golang值类型相互转换