Активные Корни Сборки Мусора 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.