Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Could some one tell me the difference between GC.GetTotalMemory(false) and GC.GetTotalMemory(true);

I have a small program and when i compared the results the first loop gives an put put < loop count 0 Diff = 32 > for GC.GetTotalMemory(true); and < loop count 0 Diff = 0 > for GC.GetTotalMemory(false); but shouldnt it be the otherway ?

Smilarly rest of the loops prints some numbers ,which are different for both case. what does this number indicate .why is it changing as the loop increase.

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace test
   struct Address
       public string Street;
   class Details
      public string Name ;
      public Address address = new Address();
   class emp :IDisposable
       public Details objb = new Details();       
       bool disposed = false;
       #region IDisposable Members
       public void Dispose()
           Disposing(true);
       void Disposing(bool disposing)
           if (!disposed)
               disposed = disposing;
           objb = null;           
           GC.SuppressFinalize(this);
       #endregion
    class Program
        static void Main(string[] args)
           long size1 = GC.GetTotalMemory(false);
           emp empobj = null;          
           for (int i = 0; i < 200;i++ )
              // using (empobj = new emp()) //------- (1)
                   empobj = new emp(); //------- (2)
                   empobj.objb.Name = "ssssssssssssssssss";
                   empobj.objb.address.Street = "asdfasdfasdfasdf";
              long size2 = GC.GetTotalMemory(false);             
              Console.WriteLine( "loop count " +i + "  Diff = " +(size2-size1));

The parameter defines whether or not to wait till a full garbage collection happens before running or not.

See GC.GetTotalMemory(Boolean) Method:

Parameters

forceFullCollection

Type: System.Boolean
true to indicate that this method can wait for garbage collection to > occur before returning; otherwise, false.

The reason that diff is still 0 could be because a GC already happend even if you pass false.

In that case when I pass true , I expected to get diff = 0 , since method waits for garbage collection . but I am getting the diff = 0 when I pass false , which is confusing me – somaraj Apr 6, 2010 at 6:28 Just adding here, If you pass a true value here there is a significant performance difference. I was performing a check within a loop and the true parameter was causing significant performance differences (that I obviously should have expected) passing a false value for the parameter is a very cheap operation and showed almost no difference in performance than no memory check. – Newey Aug 5, 2020 at 14:37

Adding to @Dror Helper, using GetTotalMemory(true) is even more dangerous than is described in the documentation.

It will run a GC multiple times, up to 20x until it gets a "stable" result. These GC's are blocking meaning all threads in the application will hang until this stable condition is reached. In a web app, this prevents the server responding to client requests.

https://github.com/microsoft/referencesource/blob/master/mscorlib/system/gc.cs#L384

public static long GetTotalMemory(bool forceFullCollection) {
        long size = GetTotalMemory();
        if (!forceFullCollection)
            return size;
        // If we force a full collection, we will run the finalizers on all 
        // existing objects and do a collection until the value stabilizes.
        // The value is "stable" when either the value is within 5% of the 
        // previous call to GetTotalMemory, or if we have been sitting
        // here for more than x times (we don't want to loop forever here).
        int reps = 20;  // Number of iterations
        long newSize = size;
        float diff;
            GC.WaitForPendingFinalizers();
            GC.Collect();
            size = newSize;
            newSize = GetTotalMemory();
            diff = ((float)(newSize - size)) / size;
        } while (reps-- > 0 && !(-.05 < diff && diff < .05));
        return newSize;
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.