C# Garbage Collection Active Roots

I'm reading about the C# garbage collector, and how the CLR builds object graphs. The chapter references different roots that could be active for the object:

• References to global objects (though these are not allowed in C#, CIL code does permit allocation of global objects)
• References to any static objects/static fields
• References to local objects within an application's code base
• References to object parameters passed into a method
• References to objects waiting to be finalized (described later in this chapter)
• Any CPU register that references an object

I was wondering if someone could give examples of these roots in code?

Thanks


Assume you run the following program:

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();
    }
}

When the program breaks into the debugger, there are 3+ objects that are not eligible for garbage collection because of the following references:

  • a Class1 object referenced by the static field foo
  • a string[] object referenced by the parameter args
  • zero or more string objects referenced by the string[] object referenced by args
  • a Class2 object referenced by the local variable bar
  • The Class3 object is eligible for garbage collection and may already have been collected or be waiting to be finalized.

    References to global objects are not allowed in C#. References in CPU registers are an implementation detail of the VM.


    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命令。

    链接地址: http://www.djcxy.com/p/19884.html

    上一篇: 什么触发了Java垃圾收集器

    下一篇: C#垃圾回收活动根