Home

Search

C# GC.Collect Examples: CollectionCount, GetTotalMemory

Use the GC.Collect method to force a garbage collection. Measure memory usage.

dot net perls

GC.Collect. The C# language is a garbage-collected language. This means that memory that is no longer referenced by your program will be reclaimed and is later reused.

With GC.Collect, we force a garbage collection to occur at any time. This might seem like a good idea, but it almost is not. It interferes with performance.

An example. Three calls to get the total memory usage on the system are present. They occur before the allocation, after the allocation, and after the forced garbage collection.
Tip: You can see that memory returns to its low level after the garbage collection.
C# program that uses GC.Collect using System; class Program { static void Main() { long mem1 = GC.GetTotalMemory(false); { // Allocate an array and make it unreachable. int[] values = new int[50000]; values = null; } long mem2 = GC.GetTotalMemory(false); { // Collect garbage. GC.Collect(); } long mem3 = GC.GetTotalMemory(false); { Console.WriteLine(mem1); Console.WriteLine(mem2); Console.WriteLine(mem3); } } } Output 45664 245696 33244

CollectionCount. This method tells us how many times garbage collection has occurred. Getting information about how often garbage collection is occurring is not always simple.
Tip: With CollectionCount and the GC.MaxGeneration property, we get this information.
Note: Because most objects die young, generations are used to optimize which elements are scanned.
And: Newer objects are scanned more often because they are most likely to have become dead.
Result: On my computer, the program resulted in 15 generation 0 garbage collections.
C# program that uses CollectionCount using System; class Program { static void Main() { // This loop does a lot of allocations! for (int i = 0; i < 100; i++) { for (int a = 0; a < 1000; a++) { System.IO.Path.GetRandomFileName(); System.IO.Path.GetRandomFileName(); } System.Threading.Thread.Sleep(1); } // Display collection counts. for (int i = 0; i <= GC.MaxGeneration; i++) { int count = GC.CollectionCount(i); Console.WriteLine(count); } } } Output 15 0 0

GetTotalMemory. This returns the number of bytes allocated. It accesses statistics about the managed heap. It returns data about the entire .NET Framework, not the specific program.
Parameter: The method receives one parameter of type bool, which lets you demand a garbage collection to occur before taking the numbers.
Bool
Next: This program shows the memory difference after allocating ten million bytes and then collecting them.
Info: We pass a bool to GC.GetTotalMemory. False indicates that an expensive collection should not be forced.
False
Usually: Forcing a GC has no benefit in programs. It just adds to the complexity. It is best to leave this parameter as false.
C# program that uses GC using System; class Program { static void Main() { long bytes1 = GC.GetTotalMemory(false); // Get memory in bytes byte[] memory = new byte[1000 * 1000 * 10]; // Ten million bytes memory[0] = 1; // Set memory (prevent allocation from being optimized out) long bytes2 = GC.GetTotalMemory(false); // Get memory long bytes3 = GC.GetTotalMemory(true); // Get memory Console.WriteLine(bytes1); Console.WriteLine(bytes2); Console.WriteLine(bytes2 - bytes1); // Write difference Console.WriteLine(bytes3); Console.WriteLine(bytes3 - bytes2); // Write difference Console.ReadLine(); } } Output 21060 Program started with these bytes. 10021092 After ten million bytes allocated. 10000032 Difference. 12860 After garbage collection. -10008232 Difference.

Managed heaps. The GC.GetTotalMemory method operates on the concept of the managed heap, not the program that you are calling it from.
And: Programs that allocate data on the managed heap are called mutators. One managed heap can have many mutators.
Note: When you invoke GC.GetTotalMemory, you will be counting the allocations from all the mutator programs.

Discussion. So when should you call GC.Collect? In my experience, you should never call it. The call will usually not do much to reduce overall memory usage.
Info: In ASP.NET, GC.Collect on one application will cause a performance hit on all web sites in the same pool.
Warning: This method adds more complexity to your program and probably even reduces overall performance.

Statistics. Here is a way to monitor memory use. You can set up a special web page or dialog in your program that reports the statistics from GetTotalMemory.
And: This item can store the previous figure in a static field, and then subtract the second from the first to see the change.

A summary. GC.Collect is best used for diagnostics purposes (like determining a base line of memory usage). Memory management is best left to the .NET Framework itself when possible.

Home

© 2007-2020 sam allen. send bug reports to info@dotnetperls.com.