【发布时间】:2011-07-11 00:06:44
【问题描述】:
Reymond Chen 在他的博客When does an object become available for garbage collection? 中写道
一个对象可以有资格 在执行期间收集 那个对象上的方法。
另外,Curt Nichols 通过this example 证明了同样的观点
public class Program
{
static void Main(string[] args)
{
new TestClass().InstanceMethod();
Console.WriteLine("End program.");
Console.ReadLine();
}
}
public sealed class TestClass
{
private FileStream stream;
public TestClass()
{
Console.WriteLine("Ctor");
stream = new FileStream(Path.GetTempFileName(), FileMode.Open);
}
~TestClass()
{
Console.WriteLine("Finializer");
stream.Dispose();
}
public void InstanceMethod()
{
Console.WriteLine("InstanceMethod");
StaticMethod(stream);
}
private static void StaticMethod(FileStream fs)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("StaticMethod");
var len = fs.Length;
}
}
输出如预期 -
Ctor
InstanceMethod
Finalizer
StaticMethod
ObjectDisposedException is thrown
在这个例子中,我无法理解 GC 如何收集临时的 TestClass 对象,因为它的成员 stream 被 StaticMethod 引用。
是的,雷蒙德说
GC 不是追踪根,而是 关于删除不存在的对象 更多使用
但是,在这个例子中,TestClass 对象仍在使用中,不是吗?
请解释在这种情况下 GC 在收集TestClass 对象时是如何正确的?此外,更重要的是,开发人员应如何防范这些情况?
【问题讨论】:
-
即使使用 release 构建,我也无法重现它。
-
@Aliostad - 不要在 Visual Studio 中按 F5。在Release模式下编译并双击生成的exe。