GC.Collect Examples
This page was last reviewed on Aug 3, 2022.
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.
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); } } }
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.
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); } } }
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.
Detail The method receives one parameter of type bool, which lets you demand a garbage collection to occur before taking the numbers.
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.
true, false
Detail Forcing a GC has no benefit in programs. It just adds to the complexity. It is best to leave this parameter as false.
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(); } }
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 baseline of memory usage). Memory management is best left to the .NET Framework itself when possible.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Aug 3, 2022 (edit link).
© 2007-2024 Sam Allen.