Best Practice for Forcing Garbage Collection in C#

前端 未结 15 1816
天命终不由人
天命终不由人 2020-11-22 12:28

In my experience it seems that most people will tell you that it is unwise to force a garbage collection but in some cases where you are working with large objects that don\

15条回答
  •  清酒与你
    2020-11-22 12:49

    I would like to add that: Calling GC.Collect() (+ WaitForPendingFinalizers()) is one part of the story. As rightly mentioned by others, GC.COllect() is non-deterministic collection and is left to the discretion of the GC itself (CLR). Even if you add a call to WaitForPendingFinalizers, it may not be deterministic. Take the code from this msdn link and run the code with the object loop iteration as 1 or 2. You will find what non-deterministic means (set a break point in the object's destructor). Precisely, the destructor is not called when there were just 1 (or 2) lingering objects by Wait..().[Citation reqd.]

    If your code is dealing with unmanaged resources (ex: external file handles), you must implement destructors (or finalizers).

    Here is an interesting example:

    Note: If you have already tried the above example from MSDN, the following code is going to clear the air.

    class Program
    {    
        static void Main(string[] args)
            {
                SomePublisher publisher = new SomePublisher();
    
                for (int i = 0; i < 10; i++)
                {
                    SomeSubscriber subscriber = new SomeSubscriber(publisher);
                    subscriber = null;
                }
    
                GC.Collect();
                GC.WaitForPendingFinalizers();
    
                Console.WriteLine(SomeSubscriber.Count.ToString());
    
    
                Console.ReadLine();
            }
        }
    
        public class SomePublisher
        {
            public event EventHandler SomeEvent;
        }
    
        public class SomeSubscriber
        {
            public static int Count;
    
            public SomeSubscriber(SomePublisher publisher)
            {
                publisher.SomeEvent += new EventHandler(publisher_SomeEvent);
            }
    
            ~SomeSubscriber()
            {
                SomeSubscriber.Count++;
            }
    
            private void publisher_SomeEvent(object sender, EventArgs e)
            {
                // TODO: something
                string stub = "";
            }
        }
    

    I suggest, first analyze what the output could be and then run and then read the reason below:

    {The destructor is only implicitly called once the program ends. } In order to deterministically clean the object, one must implement IDisposable and make an explicit call to Dispose(). That's the essence! :)

提交回复
热议问题