拥有此代码
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。