拥有此代码
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生成?
答案 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。