垃圾收集器没有更多的参考

时间:2014-03-16 00:25:20

标签: c# .net garbage-collection clr

我在C#中一直在阅读有关GC的内容,我发现有些陈述非常有趣。

说我有以下方法:

public void Foo()
{
   Animal eAnimal = new Animal();
   eAnimal.Name = "Matthew";

   GC.Collect();

   ...more code not using eAnimal...

   return;
}

据说在 GC.Collect()语句中,GC计算出代码中不再引用与 new Animal()对象相对应的内存地址因此适合处置。

据我所知,即使在 GC.Collect()语句中,也有对堆栈中 new Animal()的引用(甚至也许存储在一些CPU注册表中)。我知道如果我检查代码虽然该值存在于堆栈中,但代码的逻辑不再使用,但我认为这种分析可以在编译时完成,而不是真正在运行时。

GC如何知道即使堆栈中有一个引用到堆中,该引用也不会在程序的未来语句中以任何方式使用?

我最好的猜测是编译将此考虑在内并创建适当的指令来清除堆栈中的引用,然后使GC工作更容易。但这似乎给生成的代码增加了很多开销。

编辑:我正在阅读有关考试70-483的书,并说明:

StreamWriter stream = File.CreateText(“temp.dat”);
stream.Write(“some data”);
GC.Collect()
  

在Release模式下运行这段代码时,垃圾收集器会在那里看到   不再引用流,它将释放任何与流相关的内存 -   作家实例。

1 个答案:

答案 0 :(得分:2)

您没有从方法返回对该对象的引用,因此当您调用GC.Collect()时,它会查看对象的使用位置,并且在收集调用后看到其他任何内容都不会引用它。如您所示,调用后的代码都没有使用该对象,因此GC将安全地处理它。

MSDN Example很好地解释了与你所拥有的相似的情况。

垃圾收集操作的全面解释:http://msdn.microsoft.com/en-us/magazine/bb985010.aspx