Активные Корни Сборки Мусора C#

Я читаю о сборщике мусора C# и о том, как среда CLR строит графы объектов. Глава ссылается на различные корни, которые могут быть активны для объекта:

• ссылки на глобальные объекты (хотя они не разрешены в C#, CIL код разрешает выделение глобальных объектов)
* Ссылки на любые статические объекты / статические поля
• Ссылки на локальные объекты в база кода приложения
• Ссылки на объект параметры, передаваемые в метод
* Ссылки на объекты, ожидающие завершения (описано ниже в этой главе)
* Любой регистр CPU, который ссылается объект

Мне было интересно, может ли кто-нибудь привести примеры этих корней в коде?

спасибо

2 ответов


Предположим, вы запустите следующую программу:

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 + объекта, которые не имеют права на сборку мусора из-за следующих ссылок:

  • a Class1 объект, на который ссылается статическое поле foo
  • a string[] объект, на который ссылается параметр args
  • ноль или больше string объекты, на которые ссылается string[] объект, на который ссылается args
  • a Class2 объект, на который ссылается локальная переменная bar

на Class3 объект имеет право на сборку мусора и, возможно, уже был собран или ожидает завершения.

ссылки на глобальные объекты не допускаются в C#. Ссылки в регистрах ЦП являются деталями реализации виртуальной машины.


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.