Home > Articles > .Net Framework Articles > Measuring c# application Garbage Collection using performance counter

Measuring c# application Garbage Collection using performance counter

by Rahul Pyarelal   on Nov 18, 2016   Category: .Net Framework  | Level: Beginner  |  Views: 360    |  Points: 100   
Like this article? Bookmark and Share:
In this article we will measure garbage collection by using performance counters.

Introduction

Garbage Collector in .NET framework

What is Garbage Collector

Type of generation

Introduction

The Garbage Collection is very important technique in the .Net framework to free the unused managed code objects in the memory and free the space to the process. I will explain about the Garbage collection in this article.

Garbage Collector in .NET framework

Garbage Collector is a feature provided by the .NET common Language Runtime that helps us to cleanup unused managed object. When we have a class the represents an object in the runtime that allocates a memory space in the heap memory. All the behavior of the objects can be done in the allotted memory in the heap. This process is repeated for each newly create object, but there is a limitation to everything, Memory is not unlimited and we need to clean some used space in order to make room for new objects.

What is Garbage Collector

The heap memory is divided into number of generations. It is three generations. The Generation 0 is for short live objects, Generation 1 is for medium live objects which are moved from Generation 0. In generation 2 are mostly stable objects.

When an object is created then it will allocate the memory space which will be higher. It will be in the Generation 0 and the memory allocation will be continuous without any space between the generations of garbage collectors.

Garbage collector work on managed heap, which is nothing but a block of memory to store object. When garbage collection process is put in motion. It checks for dead object and the objects which are no longer used. Then it compacts the space of live object and tries to free more memory.

Type of generation

0 Generation (Zero):-Whenever we create an object it moves to generation 0. Garbage collector is automatically called whenever there is a need to free up heap memory. So when garbage collector runs it check whether object is still being used. It will move into next generation. This generation holds short lived object. Garbage collector initiates garbage collection process frequently in the generation. Most the object in generation 0 better for us.

1 Generation (one):- The objects which are not being used are marked for garbage collection similarly the object is moved from generation 1 to generation 2. The less number of objects in generation 1.This generation is the buffer between generation 0 and generation 2.

2 Generation: - This generation holds long-lived objects like a static and global variable that needs to be persisted for a certain amount of time. Object which are not collected in generation one. Then moved to generation 2. “Because generation 2 collections can occupy multiple segments, object that is promoted into generation 2 can be moved into an older segment. Both generation 1 and generation 2 survives can be moves to a different segment, because they are promoted to generation 2. The large object heap is not compacted, because copying large object imposes a performance penalty.

The object that needed to stay a long time in memory comes into the Generation 1 and Generation 2. One thing is very necessary. That is to share that the DC most of the time checks for only those object that are in Generation 0.

A garbage collection has the following phases:

  • A marking phase that finds and creates a list of all live objects.
  • A relocating phase that updates the references to the objects that will be compacted.
  • A compacting phase that reclaims the space occupied by the dead objects and compacts the surviving objects. The compacting phase moves objects that have survived a garbage collection toward the older end of the segment.

Before a garbage collection starts, all managed threads are suspended except for the thread that triggered the garbage collection.

The following illustration shows a thread that triggers a garbage collection and causes the other threads to be suspended.

Thread that triggers a garbage collection.

The rules for this simplified model are as follows:

  • All garbage-collectable objects are allocated from one contiguous range of address space.
  • The heap is divided into generations (more on this later) so that it is possible to eliminate most of the garbage by looking at only a small fraction of the heap.
  • Objects within a generation are all roughly the same age.
  • Higher-numbered generations indicate areas of the heap with older objects—those objects are much more likely to be stable.
  • The oldest objects are at the lowest addresses, while new objects are created at increasing addresses. (Addresses are increasing going down in Figure 1 above.)
  • The allocation pointer for new objects marks the boundary between the used (allocated) and unused (free) areas of memory.
  • Periodically the heap is compacted by removing dead objects and sliding the live objects up toward the low-address end of the heap. This expands the unused area at the bottom of the diagram in which new objects are created.
  • The order of objects in memory remains the order in which they were created, for good locality.
  • There are never any gaps between objects in the heap.
  • Only some of the free space is committed. When necessary, more memory is acquired from the operating system in the reserved address range

So in order to achieve the same below is a simple code which has one for loops.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication7
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Read();
            Console.WriteLine(" Add Tables");
           
            function();
            Console.WriteLine("out od scop");
            Console.Read();
        }
        static void function()
        {
            List str = new List(); 
            for (int i =0; i <100000 ; i++)
            {
                str.Add(DateTime.Now.ToString());
            }
            Console.Read();
        }
    }
}

So first go ahead and run the application or we can say press ctrl+F5. This will make your application running.

After that your application is running, we will run perfmon to monitor the memory. We have a console.read statement which makes sure that our ‘for’ loops do not run and we get some time to measure the performance counter. If you don’t know, what is Performance counter, so please go and see the Performance counter article.

When you click on “Add counter”, a new window will be open. After that first we need to select .NET CLR Memory. Then select the “Bytes in the heaps” and click on the project name under the “Instances of selected object” your project name will be appearing on the right side to “Added counters”.

When you click on the “Add counter” , a new window will be open. After that first we need to select “.NET CRL Memory”. Then select all require option. If you need to see how much object created in generation to select the Gen 0 collection, Gen 1 collection and Generation 2 collection by your application as show in the below screenshot.

Select Added counter as show on the above screen and that should display memory consumed by the application.

If you want to When you forcefully start to Garbage collector then call to GC.Collect() in your method. Show in below application.

static void Main(string[] args)
        {
            Console.Read();
            Console.WriteLine(" Add Tables");
           
            function();
            Console.WriteLine("out of scope");
            GC.Collect();
            int s = GC.CollectionCount();
            Console.WriteLine(s);
            Console.Read();
            
        }
        static void function()
        {
            List str = new List(); 
            for (int i =0; i <1000 ; i++)
            {
                str.Add(DateTime.Now.ToString());
               
            }
             
            Console.Read();
        }
    }

When calling the GC.Collert, see the Output of your application in screenshot.

If you are new to C# language and .NET platform below is a worth watching video covering learning fundamental with practical project: -



Like this article? Bookmark and Share:

Most viewed Articles

User Comments


No response found, be the first to review this article.

Submit feedback about this article

Please sign in to post feedback

Latest Posts