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

.net GC.COllect()似乎无法在调试模式下工作,.net,garbage-collection,.net,Garbage Collection,我正在运行下面的代码,当它在发布模式下运行时,结果完全不同。在调试模式下,它从不收集类A的对象,而在Realse模式下,它会立即收集类A的对象 有人能解释一下原因吗 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { class Program { static void M

我正在运行下面的代码,当它在发布模式下运行时,结果完全不同。在调试模式下,它从不收集类A的对象,而在Realse模式下,它会立即收集类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
    } }

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

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

在释放模式下,变量的使用仅限于实际使用的地方。在最后一次使用varaible之后,对象将进行垃圾收集


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

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

obj = null;

就在GC.Collect()之前。我认为这是一种“模拟”优化。

这不是原因。引用不会被丢弃,它被认为是非活动的,这与优化毫无关系。反之亦然;由于变量处于非活动状态,因此可以从该点开始对其进行优化。“扔掉”作为解释可能有点过于简单,对此表示同意。尽管如此,理由是正确的;在发布模式中没有保留强引用,这会阻止GC收集实例。由于在发布模式中进行了优化,引用范围仅在其上次使用之前有效,而不是在其中定义的整个代码块。上面Lucero清楚地说明了调试模式下发生的事情。请注意,如果在调用GC.Collect之后有一个try-catch子句,那么这将不起作用。更好的解决方案是在另一个方法中创建对象,以便在GC运行时引用超出范围。这里也给出了答案: