代码之家  ›  专栏  ›  技术社区  ›  Pankaj Rawat

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

  •  2
  • Pankaj Rawat  · 技术社区  · 9 年前

    我知道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
    
    2 回复  |  直到 9 年前
        1
  •  7
  •   Eric Lippert    9 年前

    我想知道GC如何决定变量的生成?

    变量首先不是GC。 引用类型的对象 是GC'd。那些物体 包含 变量,但它是 对象 其被收集。

    我认为所有变量都会进入第0代,一段时间后会进入第1代和第2代。

    不,不要用变量来思考。从对象的角度思考。新分配的对象进入第0代。如果该对象在一个集合中存活,则将其移动到第1代。如果它在另一个集合存活,则移动到第2代。

    现在你知道为什么打电话了 GetGeneration 在包含int的局部变量上,将始终返回零。这不是因为local以某种方式与gen0神奇地关联。local不是引用类型的对象,并且 也不是它的价值!

    当您将int传递给 GetGeneration int被装箱到一个对象中;该对象是新分配的,因此处于第0代 变量 .如果你通过 任何 (非空)值类型为 GetGeneration 这触发了一个分配,显然,该分配是gen0。

    同样,您的问题表明您认为GC正在查看 变量 . 不是 .它正在研究 引用类型的对象 .

    GC决定生成的大小是否重要?

    对例如,非常大的数组是从一个特殊的“大对象堆”中分配的。“超大”基本上是指85KB或更大数量级的任何对象。大型对象堆(1)未压缩,并且(2)仅在常规堆进行gen2收集时收集。

        2
  •  1
  •   Matt Timmermans    9 年前

    第0代和第1代需要较小,以便快速收集。为了使它们保持较小,在第2代中直接分配非常大的对象。