【发布时间】:2017-12-15 08:14:55
【问题描述】:
我在大对象堆的第 2 代中有一个大的 T[]。 T 是一个引用类型。我做了以下作业:
T[0] = new T(..);
- 对于 GC 的下一个 Gen0/Gen1 标记阶段,哪些对象被标记为脏?整个数组实例,还是只是
T的新实例?下一个 Gen0/Gen1 GC 标记阶段是否必须遍历数组的每一项? (这似乎没有必要,而且效率很低。) - 数组在这方面有什么特殊之处吗?如果集合是例如,它会改变答案吗?
SortedList<K, T>我添加了一个新的最大项目?
我已经阅读了许多问题和文章,包括以下内容,但我仍然认为我没有找到明确的答案。 我知道整个内存范围都被标记为脏,而不是单个对象,但是新的数组条目或数组本身是这个的基础吗?
【问题讨论】:
-
这是一个很好的问题。我不知道写屏障适用于范围。如果是这种情况,那么数组的一部分无效(因为它是连续的内存)似乎是合乎逻辑的,但实际上没有理由让整个数组无效。假设 msdn 文章中提到的 128 字节范围,并且在 x64 架构(8 字节指针大小)上,这意味着 16 项无效。我认为它不会对性能产生重大影响。但是文章似乎使用了示例值,我想知道真正的值是什么
-
查看.net core GC(raw.githubusercontent.com/dotnet/coreclr/master/src/gc/gc.cpp)的代码,似乎比文章中暗示的要复杂得多。值得注意的是,似乎有一个“卡片包”机制,引用“跟踪卡片词组”。我试图弄清楚卡包是文章中提到的“范围”,还是它上面的其他机制
-
@KevinGosse,谢谢。我假设 GC 以一种智能的方式管理代际引用,并且在 gen2 SortedList 末尾附近的插入不会为 GC 创建大量工作。
标签: c# .net arrays garbage-collection