【CoreCLR】源码探索(一)Object是什么

文章目录
  1. 1. 概述
  2. 2. Object 在内存中的结构

概述:Object 说明

相关参考

概述

.Net 开发人员必不可绕过的一个对象就是 Object。简单来说,在.NET框架中,Object 是所有类的基类,是.NET类型系统中的根类。这么理解没有问题,但是对于我们要更深入研究 CLR 还不够,不足以说明 Object 是什么。

Object 在内存中的结构

Object 在内存中的结构大致如下所示,图示只描述了几个比较重要的部分:

1738721439234

  • 对象头(ObjectHeader)
    对象头是每个对象在内存中的起始部分,它包含了对象的元数据信息,主要用于对象的管理和运行时操作。对象头通常包含以下内容:
    • 同步块索引(SyncBlock Index):用于支持对象的同步操作(如锁)。它是一个指针,指向一个同步块结构体(SyncBlock)。如果对象没有被加锁,这个索引通常为0。
    • 类型对象指针(Type Object Pointer):指向该对象的类型对象(Type Object)。类型对象包含了关于对象类型的元数据信息,例如类型名称、方法表、字段布局等。通过类型对象指针,运行时可以快速获取对象的类型信息。
  • 示例字段(Instance Fields)
    实例字段是对象存储实际数据的部分。字段的布局顺序和大小取决于字段的声明顺序和类型。例如:
    • 如果对象有多个字段,字段会按照声明顺序依次存储在内存中。
    • 字段的对齐方式会收到平台(x86\x64)和编译器设置的影响,在 x64 系统上,通过会按照 8 字节对齐。
  • 方法表(Method Table)
    方法表本身并不是对象内存结构的一部分,但它与对象紧密相关。方法表式通过类型对象指针间接访问的。方法表中包含了对象类型的所有方法的入口点(即方法的内存地址)。当调用对象的方法时,运行时会通过类型对象指针找到方法表,然后通过方法表调用相应的方法。
  • 内存对齐和填充
    为了提高内存访问效率,.Net 运行时会对对象的内存布局进行对齐处理。具体来说:
    • 对象的大小会扩展到下一个对齐边界(通过是8字节或16字节,具体取决于平台)
    • 如果对象的字段大小不足以填满对齐边界,运行时会在字段之间或对向末尾插入填充字节(Padding Bytes),以确保对象的大小符合对齐要求。
  • 数组对象的特殊结构
    如果对象是一个数组,其内存结构会稍有不同:
    • 数组对象除了包含普通对象的对象头和类型对象指针外,还会额外包含一个长度字段(Length),用于存储数组的长度
    • 数组的元素会紧随长度字段之后,按照元素类型一次存储。

更详细的结构可以参考微软提供的结构图,如下所示(本文引用的第三个链接):