C#垃圾收集活跃根

时间:2011-12-01 16:48:21

标签: c# memory-management garbage-collection clr

我正在阅读C#垃圾收集器,以及CLR如何构建对象图。 本章引用了可能对对象有效的不同根:

  

•对全局对象的引用(尽管C#,CIL中不允许这些引用)   代码确实允许分配全局对象)
  •任何参考   静态对象/静态字段
  •引用。中的本地对象   应用程序的代码库
  •引用传递的对象参数   进入方法
  •引用等待最终确定的对象   (在本章后面描述)
  •任何引用的CPU寄存器   一个对象

我想知道是否有人可以在代码中提供这些根的示例?

由于

2 个答案:

答案 0 :(得分:7)

假设您运行以下程序:

class Program
{
    static Class1 foo = new Class1();

    static void Main(string[] args)
    {
        Class2 bar = new Class2();

        Class3 baz = new Class3();
        baz = null;

        Debugger.Break();

        bar.Run();
    }
}

当程序进入调试器时,由于以下引用,有3个以上的对象不符合垃圾回收条件:

  • 静态字段Class1
  • 引用的foo对象
  • 参数string[]
  • 引用的args对象
  • string
  • 引用的string[]对象引用的零个或多个args个对象
  • 本地变量Class2
  • 引用的bar对象

Class3对象有资格进行垃圾回收,可能已经收集或等待最终确定。

C#中不允许引用全局对象。 CPU寄存器中的引用是VM的实现细节。

答案 1 :(得分:1)

class Test
    {
        static object ImARoot = new object(); //static objects/static fields

        void foo(object paramRoot) // parameters  I'm a root to but only when in foo
        {
            object ImARoot2 = new object(); //local objects but only when I'm in foo. 

            //I'm a root after foo ends but only because GC.SuppressFinalize is not called called (typically in Dispose)
            SomethingWithAFinalizer finalizedRoot = new SomethingWithAFinalizer (); 


        }
    }

如果您想了解对象在给定点的根源,可以使用SOS(在Visual Studio 2005或更高版本或WinDbg中)并使用!gcroot命令。