Signup/Sign In
LAST UPDATED: SEPTEMBER 27, 2021

C# Garbage Collection and Destructor

    From our previous tutorials, it is clear that the objects are created at run time using the new keyword. While creating a class's object, sometimes the situation may arise at the time of allocating memory to the objects: insufficient memory to create desired objects as memory is finite.

    So, to manage the memory of allocated objects, we are going to look at the concepts of Garbage Collection and Destructor in details.

    In C# language, the allocation and deallocation of memory, is automatically managed by the garbage collector. Whenever we create a new object, then the Common Language Runtime (CLR) allocates some memory space from the managed heap area, and this process of allocation of memory continues as long as the address space is available in the managed heap.

    At a certain time, due to finite availability of the memory in our system, we need to clean up the unused objects for the new ones and here the GC (Garbage Collector) comes into the picture. It manages the memory automatically and has an Optimization Engine inside it. The optimization engine helps to determine the best time to perform a collection (unused objects by the application and perform the necessary operation to free the memory).


    Heap Generations in Garbage Collection:

    The heap memory is arranged into three generations, and the amount of memory for each generation is allocated by the Common Language Runtime. The brief description of each generation is given below.

    Generation 0: In this generation, the short timespan objects are placed like temporary/local variables. At the same time, the garbage collection uses an algorithm to remove dead objects, and all the alive objects are moved into the next generation.

    Generation 1: Those objects which are not released in the generation 0, they are moved into generation 1, and the timespan of the objects in this generation is also short. As the objects live for short timespan in generation 0 as well as in generation 1, hence these generations are known as the ephemeral generations. Also, generation 1 acts as a buffer between generation 0 and generation 2.

    Generation 2: In this generation, long timespan objects are placed like a server application that contains static data (object live for a longer duration of the process). This generation is also known as full garbage collection, as it releases all objects in all the other generations.

    Let's take an example of GC.MaxGeneration

    Filename: Program.cs

    using System;
    
    namespace Studytonight
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                Console.WriteLine("Max generation supported by this system: " + GC.MaxGeneration);
            }
        }
    }

    Output:

    Max generation supported by this system: 2

    The above program returned the value 2 which indicates that, the number of generations supported by the system where the program executed.

    Note: The value of the generation is very much dependent upon the system.

    Let's take an example of GC.CollectionCount

    Filename: Program.cs

    using System;
    
    namespace Studytonight
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                Console.WriteLine("The occurrence of garbage collection in generation 0 is " + GC.CollectionCount(0));
                GC.Collect();
                Console.WriteLine("The occurrence of garbage collection in generation 0 is " + GC.CollectionCount(0));
            }
        }
    }

    Output:

    The occurrence of garbage collection in generation 0 is 0
    The occurrence of garbage collection in generation 0 is 1

    The above example demonstrates the use of the CollectionCount and the Collect method. The CollectionCount method helps us to find out if the garbage collection occurred in any specified generation. It is mandatory to provide the generation value to the CollectionCount method. In our case, we passed the generation 0 as the parameter.

    On the other hand, the Collect method is used to collect the unreferenced objects present in the heap memory. We haven't provided any value to the Collect method, but given the generation value to it, to forcibly check into the specified generation. (Second time, the output is 1, because we called GC.Collect method)


    Destructors in C#

    A destructor is a method that which is called when a class object is no longer required and is ready for grabage collection. The destructor function is preceded with a ~ (tilde) operator/symbol and it has the same name as the class. The primary purpose of destructor method is to deallocate/destroy the object or instance of classes. It is also known as Finalizer in C# programming.

    Properties of a Destructor:

    1. Destructor name must start with ~ (tilde) and must have the same name as the class.

    2. Destructor method is used in a class only and no more than one destructor is allowed in a class.

    3. Destructor can't be defined for a Structure.

    4. Destructor method can neither be inherited nor overloaded.

    5. Destructor method can neither have an access modifier nor parameters.

    6. Destructor method has no return type.

    7. Destructor method can't be called, it automatically gets invoked.

    Let's take a code example,

    using System;
    
    namespace Studytonight
    {
        public class Student
        {
            public Student()
            {
                Console.WriteLine("Default Constructor");
            }
            // the destructor
            ~Student()
            {
                Console.WriteLine("This is the destructor");    
            }
        }
    
        public class Program
        {
            public static void Main(string[] args)
            {
                Student s1 = new Student();
            }
        }
    }

    In the code above we have defined a destructor method for our class Student.

    In this tutorial, we learned about Garbage Collection (Memory Management) and Destructor method. It is important to note that, we don't invoke any of them explicitly as they get invoked automatically at certain memory conditions. We can call GC.Collect() method in a program, but generally, it is used for testing purpose. We hope this article helped you to stand at a good understanding level.

    You may also like:

    Subject Matter Expert of C# Programming at Studytonight.
    IF YOU LIKE IT, THEN SHARE IT
    Advertisement

    RELATED POSTS