我正在运行下面的代码,当它在Release模式下运行时,结果完全不同。在调试模式下,它永远不会收集A类对象,在Reaelse模式下,它会立即收集A类对象。
有人可以解释原因。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2 {
class Program
{
static void Main(string[] args)
{
A obj = new A();
B bobj = obj.objB;
GC.Collect();
GC.WaitForPendingFinalizers();
while (bobj.isLive)
{
Console.WriteLine("Is Alive!!");
}
Console.WriteLine("Is Dead!!");
Console.ReadLine();
}
}
class A:IDisposable
{
public B objB = new B();
public A()
{ }
~A()
{
objB.Dispose();
}
#region IDisposable Members
public void Dispose()
{
GC.SuppressFinalize(this);
}
#endregion
}
class B:IDisposable
{
public bool isLive = true;
#region IDisposable Members
public void Dispose()
{
this.isLive = false;
GC.SuppressFinalize(this);
}
#endregion
} }
答案 0 :(得分:4)
在调试模式下,编译器不优化局部变量。因此,对A的引用仍然存在。在发布模式下,编译器优化了用法,以便抛弃引用并收集对象。
答案 1 :(得分:3)
我刚在测试中发现了这种行为。插入
obj = null;
GC.Collect()之前的应该有所帮助。我认为这是一种“模拟”优化。
答案 2 :(得分:2)
垃圾收集器在调试模式和发布模式下处理不同的使用情况。
在发布模式下,变量的使用仅限于实际使用的位置。在最后一次使用变量之后,该对象就可以进行垃圾收集了。
在调试模式下,变量的使用范围扩展到了它的范围。这样做的原因是调试器中的监视窗口可以在整个范围内显示变量的值。