是否会将总大小超过 85kB 的集合放入大对象堆中?

Will a collection with a total size exceeding 85kB be put on the large-object-heap?

我有一个关于何时将对象放入小型对象堆和大型对象堆的问题。

我有两个大小小于 85kB 的字符串,我将它们添加到一个集合中,例如一个列表。字符串的组合大小超过 85kB。

这个集合将被视为小对象堆的一部分还是大对象堆的一部分?我认为它会是 SOH,但我不确定。

如果集合是 List<TReference> 任何大小,那么它就是 SOH。如果集合是一个 TReference[],32 位大小 <= 20k 个元素,或 64 位大小 <= 10k 个元素(32 位引用的大小为 4 字节,64 位引用大小为 8 字节),则它是 SOH .

对象的大小不是根据对象X + 对象X 引用的所有对象计算的,而只是根据X 的"direct" 大小计算的。

为什么 List<TReference>TReference[] 有区别?因为数组(技术上是一维、从 0 开始的索引数组)是 IL 语言直接支持的唯一可变长度数据类型。几乎所有其他集合类型都只是对 T[] 数组(或一堆 T[] 数组)的引用加上一些支持的数字字段。因此,例如 List<T> 是对 T[] 加上 int Length.

的引用

SOH vs LOH 的重点是"how much fast would be to move it around memory"?显然:

public class MySmallClass
{
    public byte[] WithABigObject = new byte[1024*1024];
}

虽然移动 BigObject(字节数组)会很慢,但移动 MySmallClass(仅由引用组成)非常快,因为它的大小为参考:-)

请注意,在 C# 中创建大小 >= 85k 的非数组对象非常困难,因为正如我所说,在 IL 语言直接支持的类型中,只有数组具有可变大小。其他所有类型都有固定的大小并且非常小。你需要制作一个 class 里面有 22k int 来制作一个没有数组的 LOH :-)

不带数组的 LOH 对象示例:https://ideone.com/OuVkEs。它基于多级KeyValuePair<,>(一个struct),在最底层使用Guid(最大常用struct)。结果 BigGuid128k 是 128k 的 struct。通过将其包含在您的 class 中,您的 class 将成为 LOH :-)