【发布时间】:2016-05-26 13:32:46
【问题描述】:
让我们考虑以下简单的程序:
class Program
{
class TestClass
{
~TestClass()
{
Console.WriteLine("~TestClass()");
}
}
static void Main(string[] args)
{
WeakReference weakRef;
{
var obj = new TestClass();
weakRef = new WeakReference(obj);
Console.WriteLine("Leaving the block");
}
Console.WriteLine("GC.Collect()");
GC.Collect();
System.Threading.Thread.Sleep(1000);
Console.WriteLine("weakRef.IsAlive == {0}", weakRef.IsAlive);
Console.WriteLine("Leaving the program");
}
}
在发布模式下构建时,它会按预期打印:
Leaving the block
GC.Collect()
~TestClass()
weakRef.IsAlive == False
Leaving the program
当启动 Debug 版本时(不在 Debugger 下,通常从 Windows Explorer 启动),输出不同:
Leaving the block
GC.Collect()
weakRef.IsAlive == True
Leaving the program
~TestClass()
在两个版本的调试器下运行不会改变输出。
我在调试保持对对象的弱引用的自定义集合时发现了这种奇怪的差异。
为什么调试可执行文件中的垃圾收集器不收集明显未引用的对象?
更新:
如果使用其他方法创建对象,情况会有所不同:
class Program
{
class TestClass
{
~TestClass()
{
Console.WriteLine("~TestClass()");
}
}
static WeakReference TestFunc()
{
var obj = new TestClass();
WeakReference weakRef = new WeakReference(obj);
Console.WriteLine("Leaving the block");
return weakRef;
}
static void Main(string[] args)
{
var weakRef = TestFunc();
Console.WriteLine("GC.Collect()");
GC.Collect();
System.Threading.Thread.Sleep(1000);
Console.WriteLine("weakRef.IsAlive == {0}", weakRef.IsAlive);
Console.WriteLine("Leaving the program");
}
}
它在 Release 和 Debug 版本中输出相同的输出:
Leaving the block
GC.Collect()
~TestClass()
weakRef.IsAlive == False
Leaving the program
【问题讨论】:
-
用于调试目的
-
你想说debug版没有垃圾回收?它是否记录在某处?
-
他并没有说没有调试器,只是说它的行为不同。
-
你暗示 gc 需要在你想要的时候收集死的东西。不需要这样做。
标签: c# garbage-collection