GC.COllect()似乎无法在调试模式下工作

时间:2009-04-16 11:18:39

标签: .net garbage-collection

我正在运行下面的代码,当它在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
    } }

3 个答案:

答案 0 :(得分:4)

在调试模式下,编译器不优化局部变量。因此,对A的引用仍然存在。在发布模式下,编译器优化了用法,以便抛弃引用并收集对象。

答案 1 :(得分:3)

我刚在测试中发现了这种行为。插入

obj = null;
GC.Collect()之前的

应该有所帮助。我认为这是一种“模拟”优化。

答案 2 :(得分:2)

垃圾收集器在调试模式和发布模式下处理不同的使用情况。

在发布模式下,变量的使用仅限于实际使用的位置。在最后一次使用变量之后,该对象就可以进行垃圾收集了。

在调试模式下,变量的使用范围扩展到了它的范围。这样做的原因是调试器中的监视窗口可以在整个范围内显示变量的值。