c# - 垃圾收集如何决定变量的生成

标签 c# memory-management garbage-collection

我知道 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/

相关文章:

c# - C# 中时间跨度的总和

java - 为什么 Java System.gc() 没有按预期工作?

C Realloc 导致段错误

javascript - 替换文档正文时是否收集了内联 javascript 垃圾?

c# - .NET WinForm GC 问题

c# - anchor 标签助手在新窗口选项卡中打开 View

c# - linq to sql loadwith 与 associatewith

java - 对象可以在老年代创建吗?

c# - 异步修饰符和等待运算符与委托(delegate)和线程有何不同?

c++ - 如何防止 mmap() 分配的内存空间被 'new' 调用分配?