【发布时间】:2014-04-21 07:23:17
【问题描述】:
我一直在阅读有关 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 模式下运行这段代码时,垃圾收集器会看到 不再引用流,它将释放与流相关的任何内存- 编写器实例。
【问题讨论】:
-
但是您描述的方式是唯一可行的方式。这有什么好惊讶的?在函数返回之前,所有这些引用都需要在某个时候“释放”。为什么不在打电话给
GC.Collect()之前做呢? -
Supposedly in the GC.Collect() statement, the GC figures out that the memory address corresponding the the new Animal() object is not longer referenced in the code and thus is appropriate to dispose.根据谁? -
@Kyle,我编辑了我的问题。
-
@JonathonReinhart,好吧,不要假设 Collect() 和 return 之间没有代码。我会在我的问题中解决这个问题。
标签: c# .net garbage-collection clr