C # Сборка мусора Активные корни - PullRequest
7 голосов
/ 01 декабря 2011

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

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

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

Спасибо

Ответы [ 2 ]

7 голосов
/ 01 декабря 2011

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

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 #.Ссылки в регистрах ЦП являются подробностями реализации ВМ.

1 голос
/ 01 декабря 2011
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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...