.NET CLR:运行时如何计算对象的大小?

.NET CLR: How does runtime calculate size of object?

对于大小超过 85kb 的对象,.NET 中有 大对象堆。据我了解,堆中对象的大小是这样计算的

  1. 原始类型和值类型实例的所有属性和字段的大小(因为它们存储在父实例中)
  2. 对 类 其他实例的引用大小(因为它们是分开存储的)。

示例:

  1. 10 个引用类型对象(每个 10kb)和一个包含所有对象的引用类型对象 => 所有对象应该不被放入 LOH
  2. 2 个引用类型对象(每个 86kb)和包含所有对象的引用类型对象 => LOH 中的 2 个对象但通常堆中的最后一个

计算模式是否正确?我的例子正确吗?

CLR中引用类型的分配成本由固定开销(取决于体系结构)加上其成员总数(最终都是值,甚至是引用,4字节或8字节)组成.

参考: What is the memory overhead of a .NET Object

它不分配引用对象的内存space,只分配引用值。

如果您分配一个 10KB 的对象,它不会命中 LOH。

如果分配一个 10 x 10KB 的数组 classes,列表和对象都不会在 LOH 中。该列表实际上是一个 10 x 架构参考大小的数组

如果您的 class 是一个 struct,该列表将包含容纳 10KB 结构所需的内存 space,10 次,理论上这会插入列表(并且由于值类型,对象也是)在 LOH 上。

不要忘记,List<T> 根据算法(当前为 x*2)分配 space。 space 不是你放在列表中的内容,而是列表当前有多少 Capacity

LOH 分配限制是运行时的一个实现细节,可能会发生变化。看看它是如何工作的很有趣,但不要构建任何依赖于它当前工作方式的东西。