Generations

The garbage collector segregates the managed heap into three divisions or generations:

  • Generation 0
  • Generation 1
  • Generation 2

The idea behind this is to optimize the application by handling long-lived and short-lived objects in memory separately. For example, if we have determined that object a is a long-term object used during the application execution, then, ideally, the garbage collector would not want to check through this object on every occasion in order to see whether it is still valid. 

Instead, the garbage collector classifies short-term objects in generation 0 and long-term objects in generation 1 or 2. Only objects present in generation 0 are checked during every run of the garbage collection. 

On the other hand, the objects present in higher generations are not checked as frequently. Therefore, this avoids unnecessary checks and improves the performance of the overall application.

Generation 0 is the youngest generation and all new objects are allocated to generation 0. Generation 1 objects contain objects that live longer. Similarly, generation 2 consists of the longest living objects in the application execution. Let's go through the following example to see how generations help in optimizing application performance.

Let's say we have an application, A, which is declaring different objects during execution. The square brackets indicate the different divisions or generations maintained by the garbage collector. Each of the following steps indicates a particular stage during the application execution.

Please note that the following example is just for explanation purposes only. The garbage collection calls will depend on different factors and are not necessarily be based upon the scope of the function execution.

Let's take a look at the following code example and see how it works. In the code example, we have declared a private ReturnResult function, which does not have any input parameter and returns an output parameter of the object type. In this function, just for the sake of explanation, we have declared some variables and are returning back one variable, a, to the calling function. Now, let's execute the code as follows:

static void Main(string[] args)
{
object a = ReturnResult();
}

static private object ReturnResult()
{
object a = new object();
object b = new object();
object c = new object();
object d = new object();
object e = new object();
return a;
}

When the application execution begins, the application calls the ReturnResult function. Then, in the function, when the execution encounters the new keyword, the garbage collector gets triggered. As all the variables are newly created variables, these variables will be added to generation 0:

Now, suppose that in the next statement, we return the execution to the main function and pass object aBy doing so, the program execution shifts to the main operation. However, as we are just returning a, all the other b, c, d, and e objects will no longer be required in the application.

Additionally, we are also declaring new objects, f, g, and h, in the main program.

If the garbage collector is called during this time, it will identify that object a is still required in the program execution but all other objects can be released. Therefore, the garbage collector will reclaim the memory in the variables b, c, d, and e. The new objects, f, g, and h, will be added to generation 0. For object a, the garbage collector will assume that it's a long-lived object and this will be moved to the generation 1 division.

This is what the generations now look like:

Now, let's suppose that, again, the main program calls for another ReturnResultFinal function passing object a. The newly added program does not return anything back. The following is the code implementation for this:

static void Main(string[] args)
{
object a = ReturnResult();
ReturnResultFinal(a);
}
static private object ReturnResult()
{
object a = new object();
object b = new object();
object c = new object();
object d = new object();
object e = new object();
return a;
}
static private void ReturnResultFinal(object a)
{
}

At this stage, the garbage collector can determine that all the other variables can be removed from the memory except a. During this time, it can also determine that this object can be promoted to generation 2. This is what the generations now look like:

Before we move on to the next topic, let's briefly go through the mark-compact algorithm, used by the garbage collector.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.174.204