我知道 GC 有 3(0、1、2)代,但我想知道 GC 如何决定变量的代数?
我认为所有变量都进入第 0 代,一段时间后移动到第 1 代和第 2 代。GC 决定生成的大小是否重要?
程序 1:
private static void Main(string[] args)
{
int a = 0;
string name = "Test";
var byteArray = new byte[10];
byteArray[4] = 4;
Console.WriteLine($"Generation of array {GC.GetGeneration(byteArray)}");
Console.WriteLine($"Generation of local int variable {GC.GetGeneration(a)}");
Console.WriteLine($"Generation of local string variable {GC.GetGeneration(name)}");
}
结果
Generation of array 0
Generation of local int variable 0
Generation of local string variable 0
程序 2:
private static void Main(string[] args)
{
int a = 0;
string name = "Test";
var byteArray = new byte[100000000];
byteArray[4] = 4;
Console.WriteLine($"Generation of array {GC.GetGeneration(byteArray)}");
Console.WriteLine($"Generation of local int variable {GC.GetGeneration(a)}");
Console.WriteLine($"Generation of local string variable {GC.GetGeneration(name)}");
}
结果
Generation of array 2
Generation of local int variable 0
Generation of local string variable 0
最佳答案
I'm wondering how GC decides the generation for a variable?
变量从一开始就不会被 GC。 引用类型的对象 是 GC 的。这些对象包含变量,但收集的是对象。
I thought all variables go into generation 0 and after some time move to generations 1 and 2.
没有。不要考虑变量。从对象的角度思考。新分配的对象进入 gen0。如果该对象在一个集合中幸存下来,它将被移动到 gen1。如果它在另一个集合中幸存下来,它将移至 gen2。
现在您知道为什么对包含 int 的局部变量调用 GetGeneration
总是返回零。这并不是因为 local 以某种方式神奇地与 gen0 相关联。 local 不是引用类型的对象,它的值也不是!
当您将 int 传递给 GetGeneration
时,int 被装箱到一个对象中;该对象是新分配的,因此它在第 0 代中。这不会告诉您有关变量的任何信息。如果您将任何(非空)值类型传递给触发分配的 GetGeneration
,显然该分配是 gen0。
同样,您的问题表明您认为 GC 正在查看变量的生命周期。 不是。它正在查看引用类型对象的生命周期。
Is it size matter for GC to decide the generation?
是的。例如,非常大的数组是从一个特殊的“大对象堆”中分配的。 “非常大”,基本上是指 85KB 或更大数量级的任何对象。大型对象堆 (1) 未压缩,并且 (2) 仅在常规堆执行 gen2 收集时收集。
关于c# - 垃圾收集如何决定变量的生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41521919/