.net NET CLR如何处理空类型中的内存开销?

.net NET CLR如何处理空类型中的内存开销?,.net,clr,.net,Clr,所有.NET类都将同步块和类型指针存储为其实例的一部分。32位进程总共占用8字节,64位进程总共占用16字节。但是,空类型实例的对象大小分别为12和24字节 我看到一些文章说这是一个对齐问题,但由于同步块和类型句柄是指针大小的,我不明白为什么需要添加任何填充 其他文章说垃圾收集器需要它,但是它对开销有什么作用呢?它不能在那里存储任何内容,因为如果类型具有实例字段,那么实际上会使用额外的空间。垃圾收集器是否在对象终结后和释放前的某个时间使用该内存做了一些事情,需要放置一些东西(可能是指针) 以下是

所有.NET类都将同步块和类型指针存储为其实例的一部分。32位进程总共占用8字节,64位进程总共占用16字节。但是,空类型实例的对象大小分别为12和24字节

我看到一些文章说这是一个对齐问题,但由于同步块和类型句柄是指针大小的,我不明白为什么需要添加任何填充

其他文章说垃圾收集器需要它,但是它对开销有什么作用呢?它不能在那里存储任何内容,因为如果类型具有实例字段,那么实际上会使用额外的空间。垃圾收集器是否在对象终结后和释放前的某个时间使用该内存做了一些事情,需要放置一些东西(可能是指针)

以下是我读过的一些关于空类型大小的文章:

:

如果创建一个没有字段的对象并在调试器中查看它,您会注意到它的大小实际上是12字节,而不是8字节。对于64位进程,对象将是24字节。这是因为最小尺寸基于对齐。谢天谢地,这个“额外”4字节的空间将被一个字段使用

:

“最小”大小分别为12字节和24字节。换句话说,你不能有一个仅仅是开销的类型。请注意“Empty”类如何占用与创建对象实例相同的大小…实际上有一些空闲空间,因为CLR不喜欢在没有数据的对象上操作

:

如前所述,当前GC实现需要至少12字节的对象实例。如果一个类没有定义任何实例字段,它将带来4字节的开销。其余的8个字节将被对象头(可能包含一个syncblk编号)和TypeHandle占用


是的,即使是空类,通常存储对象字段的对象部分也需要4/8字节。所以一个完全空的类在32位模式下仍然需要4+4+4=12字节,在64位模式下需要8+8+8=24字节。当对象存在时,这些额外的4/8字节根本不被使用

释放对象时需要此存储。然后,它可以成为堆段的空闲块列表的一部分。如果堆段包含固定对象且无法完全压缩,则会发生这种情况。在这种情况下,同步块在调试生成中设置为-1,类型句柄设置为内部伪FreeObject类型。对象大小需要4个字节


从clr/src/vm/gcsmp.cpp文件SetFree()函数中可见。

啊,我知道发生了什么

数组将其长度存储为实例字段数据(在类型指针之后)的前4个或8个字节(分别在32位和64位系统中)。为了获得内存使用量的大小,CLR从方法表(由类型指针指向)中获取基本大小,并将长度乘以每项大小(它也从方法表中获取)

换句话说,公式是:

内存大小=基本大小+长度*项目大小

CLR的实现者不希望为数组和其他类型分别使用一个公式和一个不同的公式,而是希望为这两个类型都使用一个公式,这样就不需要在获取内存大小时使用任何条件逻辑

但这怎么行呢?其他对象类型不会在其实例字段数据的前4或8个字节中存储长度

键是存储在方法表中的项大小。对于非数组类型,项大小为0。这意味着无论实例字段数据的前4或8个字节中存储的值是多少,length*项大小始终为0,并且该公式将起作用

但是,即使实例字段数据的前4或8个字节的值无关紧要,仍然需要分配它以防止访问冲突


感谢Hans为我指出了SetFree方法。当我看到CLR本质上是在将任意对象转换为一维字节数组时,我意识到它假设一切都可以以这种方式转换,而对原因的调查让我得出了这个答案。

“空类型实例的对象大小是12和24字节”-你在什么地方读过吗?对齐是一个非常重要的处理器实现细节。它提供了.NET内存模型的基本保证。原子性很重要,尤其是对于对象引用。没有它,您无法编写线程化代码。@dcastro我编辑了我的问题,以包括我读过的一些关于空类型大小的文章的引用。@HansPassant,但是类型/同步块指针的8字节和16字节已经对齐。我不确定12字节和24字节大小如何有助于对齐。对。但是8已经是4的倍数了。16已经是8的倍数了。谢谢你告诉我SetFree函数!看到这种方法非常有用,让我意识到为什么需要额外的内存。看起来不仅仅是在对象转换为FreeObject类型之后才需要额外的字节。但它可以转换成这种类型,因为最小大小要求意味着长度字段总是有空间,而FreeObject类型基本上是一维字节数组。我很好奇为什么这个答案被否决了。在我看来,OP在研究这个问题上做得非常出色。