哪一代静态可读成员将被分配

  • 本文关键字:成员 分配 静态 一代 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,因此AppDomain的寿命不会为GC'd。因此,将其立即放入Gen2(如大物体)而不是在Gen0&中分配是有意义的。然后将其从Gen0移至Gen2。不幸的是,我无法确认是否是这种情况(我找不到使用windbg的数组)。

因此,重申问题 - 该static readonly成员将分配给哪个GC生成?

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

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

当前存在不存在的优化来检查此"分配到可读静态字段"方案并分配GEN2中的数组。可以吗?或许。对于非常有限的分配/对象,我不值得复杂性。它今天不存在,因此遵循通常的分配/促销规则。

Adriaan Stander的一部分答案

从.net中了解垃圾收集

首先创建对象时,将其放入0代。当填充0代时,调用了垃圾收集器。在第一代垃圾收集中生存的物体被提升为下一个更高一代,第1代。生存在第一代垃圾收集中的物体被提升为第二代和最高一代,第2代。该算法有效地适用于垃圾对象的收集很快。请注意,第2代是垃圾收集器支持的最高一代

因此,它不会立即在gen2上开始,它将进行gen0-> gen1-> gen2。

最新更新