2012-04-01 63 views
0

jit编译器和clr维护指向堆中对象或为空的应用程序根目录。 GC从这些根中创建一个图并标记堆中所有在此图中引用的对象 - 其余部分是垃圾。
我的问题是:根如何变为空?
显而易见的情况是,在代码中明确将变量设置为null。 但是,如果不是? jit/clr如何知道何时将根设置为空?GC和应用程序根

+0

再一种情况是:当您离开作用域时,在代码块中定义的局部变量变得无法访问会导致您的函数堆栈框架松动,从而引发此对象。 – 2012-04-01 22:38:54

回答

1

我的理解是,包含在应用程序根目录中的指针不是设置为空。这有点违反直觉(恕我直言),因为它看起来似乎是处理对象的最快方式是简单地摆脱指向它的指针,就像FAT文件系统简单地标记FAT条目以删除文件,而实际上并没有将该指针跟在磁盘上的字节并将其设置为零。我错过了一个涉及到这个问题的面试问题,所以我读了一下它,尽管它对我们每天担心的事情几乎没有适用性。

无论如何...... Jeffrey Richter在十二年前写了一篇MSDN文章来解决这个问题。从他的文章中我学到了以下内容。

当GC运行时,它假定所有应用程序根指向不可访问的对象。它走的根源,跟随他们到堆上的对象(或发现他们没有指向任何有效的东西)。它以递归方式执行此操作,从而构建可访问对象的新图形。然后它走过堆栈,移动有效的对象并修正它们的指针 - 其效果是将堆栈顶部的空闲内存合并起来。在这个过程中的某一时刻,可到达对象的图形被复制回应用程序根目录,取而代之。我不确定这是否发生在堆压缩之前或之后。

12月12日和1月13日MSDN杂志的问题还包含一篇关于C#内存管理的文章。我没有阅读它,但计划 - 它可能会澄清所有这一切。