.Net垃圾收集器中写入障碍的详细信息

时间:2017-12-15 08:14:56

标签: c# .net arrays garbage-collection

我在大对象堆的第2代中有一个大的T[]T是引用类型。我做了以下任务:

T[0] = new T(..);

  • 对于GC的下一个Gen0 / Gen1标记阶段,哪个(哪些)对象被标记为脏?整个数组实例,还是T的新实例?下一代Gen0 / Gen1 GC标记阶段是否必须遍历阵列的每个项目? (这似乎是不必要的,非常低效。)
  • 阵列在这方面是否特别?如果收集是例如,它会改变答案吗?一个SortedList<K, T>,我添加了一个新的最大项目?

我已经阅读了很多问题和文章,包括下面的问题和文章,但我仍然认为我没有找到明确的答案。 我知道整个内存范围被标记为脏,而不是单个对象,但新数组条目或数组本身是否为此基础?

card table and write barriers in .net GC

Garbage Collector Basics and Performance Hints

2 个答案:

答案 0 :(得分:0)

非常确定其跟踪数组插槽,而不是持有对数组对象本身的引用的根。 顺便说一句,如果特定卡设置为脏卡,则必须扫描4k的内存。我现在使用Windows自己的机制在某处读取了内容,如果您将感兴趣的内存范围写入其中,则可以获取通知。

答案 1 :(得分:0)

  

在下一个GC的Gen0 / Gen1标记阶段,哪些对象被标记为脏对象?整个数组实例,还是只是T的新实例?

包含数组开头的

128B块将被标记为脏。新创建的实例(new T())将是一个新对象,因此将首先通过不带卡表的Gen 0集合对其进行检查。

为简单起见,假设数组的开头在128B边界上对齐,这意味着第一个128B将无效,因此假设T是引用类型,并且您使用的是64位系统,这是下一个收集期间要检查的前16个项目。

  

下一个Gen0 / Gen1 GC标记阶段是否必须遍历数组的每个项目? (这似乎是不必要的,而且效率很低。)

这16到32个项目,具体取决于此体系结构中的指针大小。

  

是数组特别在这方面?难道更改答案,如果集合了如一个排序列表和本人增加了新的,最大项?

数组没有特殊。 A SortedList<K,T>保持两个阵列内部,所以多个块最终会脏在平均情况下。