我正在阅读C#垃圾收集器,以及CLR如何构建对象图。 本章引用了可能对对象有效的不同根:
•对全局对象的引用(尽管C#,CIL中不允许这些引用) 代码确实允许分配全局对象)
•任何参考 静态对象/静态字段
•引用。中的本地对象 应用程序的代码库
•引用传递的对象参数 进入方法
•引用等待最终确定的对象 (在本章后面描述)
•任何引用的CPU寄存器 一个对象
我想知道是否有人可以在代码中提供这些根的示例?
由于
答案 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命令。