将分配哪一代静态只读成员

时间:2017-12-21 15:15:59

标签: c# .net

拥有此代码

class Program
    {
        private static readonly int[] s_numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        static void Main(string[] args)
        {
            foreach (int number in s_numbers)
            {
                WriteLine(number);
            }

            WriteLine("Press ENTER to close the app.");
            ReadLine();
        }
    }

我想知道哪个s_numbers数组将被分配(哪一代)? 我的推理如下 - 因为这是static readonly成员,它不会是nulled,因此GC'd的生命周期不会是AppDomain 1}}。因此,将它直接放入GEN2是有意义的(就像使用大型物体一样)而不是将它分配到GEN0&然后将它从GEN0移动到GEN2。 不幸的是,我无法确认是否是这种情况(我无法使用WinDbg找到此数组)。

所以重申一个问题 - 这个static readonly成员将分配哪个GC生成?

2 个答案:

答案 0 :(得分:5)

readonly是个谎言。你认为readonly主要只是一个指南,而不是一个实际的规则 - 至少在大多数运行时:

private static void ThisWorksFine()
{
    typeof(Program).GetField("s_numbers", BindingFlags.NonPublic | BindingFlags.Static)
        .SetValue(null, null);
}

目前尚无优化来检查此情况"分配给只读静态字段"方案并在GEN2中分配数组。可以吗?也许。对于数量非常有限的分配/对象,我打赌它并不值得复杂。它今天不存在,所以它遵循通常的分配/促销规则。

答案 1 :(得分:2)

Part of Adriaan Stander‘s answer

来自Understanding garbage collection in .Net

  

首次创建对象时,将其置于第0代。当填充第0代时,将调用垃圾收集器。在第一代垃圾收集中存活的对象被提升到下一代更高代,第1代。在第1代中存活垃圾收集的对象被提升到下一代和最高代,第2代。该算法有效地用于垃圾对象的集合,因为它很快。请注意,第2代是垃圾收集器支持的最高代

因此它不会立即在GEN2上启动它将进入GEN0-> GEN1-> GEN2。