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

标签 .net clr

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

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

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

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

Performance Considerations of Class Design and General Coding in .NET :

If you made an object with no fields and looked at it in the debugger, you would notice that its size is actually 12 bytes, not 8. For 64-bit processes, the object would be 24 bytes. This is because the minimum size is based on alignment. Thankfully, this "extra" 4 bytes of space will be used by a field.

Of memory and strings :

There’s a "minimum" size of 12 bytes and 24 bytes respectively. In other words, you can’t have a type which is just the overhead. Note how the "Empty" class takes up the same size as creating instances of Object… there’s effectively some spare room, because the CLR doesn’t like operating on an object with no data.

Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects :

As discussed previously, the current GC implementation needs an object instance of at least 12 bytes. If a class does not have any instance fields defined, it will carry an overhead of 4 bytes. The rest of the 8 bytes will be taken up by the Object Header (which may contain a syncblk number) and TypeHandle.

最佳答案

啊,我明白是怎么回事了。

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

换句话说,公式是:

memory size = base size + length * item size

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

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

key是item size,保存在method表中。对于非数组类型,项目大小为 0。这意味着无论实例字段数据的前 4 或 8 字节中存储的值如何,长度 * 项目大小始终为 0,并且公式有效。

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

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

关于.net - .NET CLR 如何处理空类型的内存开销?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26952077/

相关文章:

.net - F# 和鸭式打字

C# 读取 XLS (XLSX) 文件和填充数据网格的最佳方式

c# - for循环进入0% cpu hang

c++ - C++ CLR 值类型上需要 pin_ptr,为什么?

c# - 将配置设置存储到 .NET 应用程序的最佳做法是什么?

c# - 计算增减百分比

c# - TaskFactory.StartNew 行为

c# - 我们可以在 DotNet 类库项目中使用 global.asax 文件吗

c# - GC.Collect 不调用 IronPython 析构函数

c# - 检索 JIT 输出