GC.COllect() doesnt seem to work in debug mode

2019-02-25 06:52发布

问题:

I am running the code below and the result is totally different when it runs in Release mode. While in Debug mode, it never collects the object of class A and in Reaelse mode it immediately collects the object of class A.

Can someone explain why.

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
    } }

回答1:

In Debug mode, the compiler does not optimize the local variables. Therefore, the reference to A still exists. In Release mode, the compiler optimized the usage so that the reference is thrown away and the object can be collected.



回答2:

I just found this behavior in my tests. Inserting

obj = null;

right before GC.Collect() should help. I think that is kind of "simulated" optimization.



回答3:

The garbage collector handles variable usage differently in debug mode and release mode.

In release mode the usage of a variable is only where it's actually used. After the last use of the varaible, the object is up for garbage collection.

In debug mode the usage of a varaible is expanded to it's scope. The reason for this is so that the watch window in the debugger can show the value of a variables throughout it's scope.