HI WELCOME TO Sirees
Showing posts with label .net. Show all posts
Showing posts with label .net. Show all posts

.Net Garbage Collection and Finalization Queue

Finalize is a special method that is automatically called by the garbage collector (GC) before the object is collected. This method is only called by the GC. The destructor in C# is automatically translated into Finalize. You can see the IL code using IDASM where you will see that destructor is renamed to finalize.
  1. public class A
  2. {
  3. ~A()
  4. {
  5. Console.WriteLine("Class A Destructor");
  6. //Clean up unmanaged resources here
  7. }
  8. }
The CLR translate the above C# destructor to like this:
  1. public override void Finalize()
  2. {
  3. try
  4. {
  5. Console.WriteLine("Class A Destructor");
  6. //Clean up unmanaged resources here
  7. }
  8. finally
  9. {
  10. base.Finalize();
  11. }
  12. }

Fundamental of Finalization

When a new object is created, the memory is allocated in the managed heap. If newly created object have a Finalize() method or a destructor then a pointer pointing to that object is put into the finalization queue. Basically, finalization queue is an internal data structure that is controlled and managed by the GC. Hence each pointer in finalization queue points to an object that have its Finalize method call before the memory is reclaimed.
In the below fig. the managed heap contains 10 objects and objects 2,3,5,6,and 10 also contains the Finalize method. Hence pointers to these objects were added to the finalization queue.


When the garbage collector starts go through the roots, it make a graph of all the objects reachable from the roots. The below fig. shows a heap with allocated objects. In this heap the application roots directly refer to the objects 1,3,4,6 and object 3 & 6 refers to the objects 8 & 10. Hence all these objects will become the part of the live objects graph.

The objects which are not reachable from application's roots, are considered as garbage since these are not accessible by the application. In above heap objects 2,5,7,9 will be considered as dead objects.
Before the collections for dead objects, the garbage collector looks into the finalization queue for pointers identifies these objects. If the pointer found, then the pointer is flushed from the finalization queue and append to the freachable queue .The freachable queue is also an internal data structure and controlled by the garbage collector. Now each and every pointer with in the freachable queue will identify an object that is ready to have its Finalize method called.
After the collection, the managed heap looks like below Fig. Here, you see that the memory occupied by objects 7 and 9 has been reclaimed because these objects did not have a Finalize method. However, the memory occupied by objects 2 and 5 could not be reclaimed because their Finalize method has not been called yet.

When an object's pointer entry move from the finalization queue to the freachable queue, the object is not considered garbage and its memory is not reclaimed. There is a special run-time thread that is dedicated for calling Finalize methods. When there is no entry in the freachable queue then this thread sleeps. But when there is entry in the freachable queue, this thread wakes and removes each entry from the queue by calling each object's Finalize method.

The next time the garbage collector is invoked, it sees that the finalized objects are truly garbage, since the application's roots don't point to it and the freachable queue no longer points to it. Now the memory for the object is simply reclaimed.

Note

  1. The two GCs are required to reclaim memory used by objects that have Finalize method.
What do you think?
I hope you will enjoy these deep tips about garbage collector with finalize method in .net framework. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

.Net Garbage Collection in depth

Memory management is the main concern for any application whether application is window based or web based. In .Net, CLR has a garbage collector that executes as a part of our program and responsible for reclaiming the memory of no longer used objects. Garbage collector free the memory for objects that are no longer referenced and keeps the memory for future allocations.

Advantage of Garbage Collector

  1. Allow us to develop an application without having worry to free memory.
  2. Allocates memory for objects efficiently on the managed heap.
  3. Reclaims the memory for no longer used objects and keeps the free memory for future allocations.
  4. Provides memory safety by making sure that an object cannot use the content of another object.

Memory Allocation in Managed Heap

The managed heap is a series of allocated memory segments (approx 16Mb in size each) to store and manage objects. The memory for newly created object is allocated at the next available location on the managed heap. If there is available free memory, the garbage collector doesn't search the dead objects for memory reclaim and memory allocations has been done very fast. If the memory is insufficient to create the object, the garbage collector search the dead objects for memory reclaim for the newly object.


An object is created using the new operator. This operator first makes sure that the bytes required by the new object fit in the reserved region (committing storage if necessary). If the object fits, NextObjPtr points to the object in the heap and object's constructor is called and the new operator returns the address of the object.

Key points about Garbage Collector

  1. All objects in the heap are allocated from one contiguous range of memory address and heap is divided into generations so that it is easy to eliminate the garbage objects by looking at only a small fraction of the heap.
  2. Gen 0 and Gen 1 occupy a single segment known as the ephemeral segment. Gen 2 is a set of further segments and the large object heap is yet another group of segments.
  3. Almost, all objects with-in a generation are of the same age.
  4. The newest objects are created at higher memory address while oldest memory objects are at lowest memory address with in the heap.
  5. The allocation pointer for the new objects marks the boundary between the allocated and free memory.
  6. Periodically the heap is compacted by removing the dead objects and sliding up the live objects towards the lower memory address end of the heap as shown in above fig.
  7. The order of objects (after memory reclaims) in memory remains the same as they were created.
  8. There are never any gaps among the objects in the heap.
  9. Only some of the free memory is committed when required and more memory is acquired from the OS in the reserved address range.

Generations in Managed Heap

The managed heap is organized into three generations so that it can handle short lived and long lived objects efficiently. Garbage collector first reclaim the short lived objects that occupy a small part of the heap.

  1. Generation 0

    This is the youngest generation and contains the newly created objects. Generation 0 has short-lived objects and collected frequently. The objects that survive the Generation 0 are promoted to Generation 1.
    Example : A temporary object.
  2. Generation 1

    This generation contains the longer lived objects that are promoted from generation 0. The objects that survive the Generation 1 are promoted to Generation 2. Basically this generation serves as a buffer between short-lived objects and longest-lived objects.
  3. Generation 2

    This generation contains the longest lived objects that are promoted from generation 1 and collected infrequently.
    Example : An object at application level that contains static data which is available for the duration of the process.

Garbage Collector Working Phase

  1. Marking Phase

    In this phase garbage collector finds and creates a list of all live objects.
  2. Relocating Phase

    In this phase garbage collector updates the references to the objects that will be compacted.
  3. Compacting Phase

    In this phase garbage collector reclaims the memory occupied by the dead objects and compacts the surviving objects. The compacting phase moves the surviving objects toward the older end of the memory segment.

Note

  1. The large object heap is not compacted, because copying large objects imposes a performance penalty.

Garbage Collection Algorithm

Garbage collector determine whether any object in the heap is dead or not being used by the application. If such objects exist then memory used by these objects can be reclaimed. But how garbage collector know about these objects?
Each and every application has a set of roots and these identify the storage locations for the objects on the managed heap.
Example : All the global, static objects pointers and all the local variable/ parameter object pointers on the thread's stack in the application are considered part of the application's roots. More over any CPU registers containing pointers to objects in the managed heap are also considered a part of the application's roots.
The list of active roots is maintained by the JIT compiler and CLR, and is made accessible to the garbage collector's algorithm.

Memory Reclaim Process

Now the garbage collector starts go through the roots and make a graph of all the objects reachable from the roots. The below fig. shows a heap with allocated objects. In this heap the application roots directly refer to the objects 1,3,4,6 and object 3 & 6 refers to the objects 8 & 10. Hence all these objects will become the part of the live objects graph.
The objects which are not reachable from application's roots, are considered as garbage since these are not accessible by the application. In above heap objects 2,5,7,9 will be considered as dead objects.

The garbage collector then remove the dead objects from the heap and live objects will move toward the older end of the memory segment as shown in below fig. Garbage collector also updates all the references(including root references) to the moving objects in the heap.
What do you think?
I hope you will enjoy these deep tips about garbage collector in .net framework. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

Difference Between Finalize and Dispose Method

.NET Framework provides two methods Finalize and Dispose for releasing unmanaged resources like files, database connections, COM etc. This article helps you to understand the difference between Finalize and Dispose method.
Difference between Dispose & Finalize Method
Dispose
Finalize
It is used to free unmanaged resources like files, database connections etc. at any time.
It can be used to free unmanaged resources (when you implement it) like files, database connections etc. held by an object before that object is destroyed.
Explicitly, it is called by user code and the class which is implementing dispose method, must has to implement IDisposable interface.
Internally, it is called by Garbage Collector and cannot be called by user code.
It belongs to IDisposable interface.
It belongs to Object class.
It's implemented by implementing IDisposable interface Dispose() method.
It's implemented with the help of destructor in C++ & C#.
There is no performance costs associated with Dispose method.
There is performance costs associated with Finalize method since it doesn't clean the memory immediately and called by GC automatically.

Example for implementing the dispose method

  1. public class MyClass : IDisposable
  2. {
  3. private bool disposed = false;
  4. //Implement IDisposable.
  5. public void Dispose()
  6. {
  7. Dispose(true);
  8. GC.SuppressFinalize(this);
  9. }
  10.  
  11. protected virtual void Dispose(bool disposing)
  12. {
  13. if (!disposed)
  14. {
  15. if (disposing)
  16. {
  17. // TO DO: clean up managed objects
  18. }
  19. // TO DO: clean up unmanaged objects
  20.  
  21. disposed = true;
  22. }
  23. }
  24. }

Example for implementing Finalize method

If you want to implement Finalize method, it is recommended to use Finalize and Dispose method together as shown below:
  1. // Using Dispose and Finalize method together
  2. public class MyClass : IDisposable
  3. {
  4. private bool disposed = false;
  5. //Implement IDisposable.
  6. public void Dispose()
  7. {
  8. Dispose(true);
  9. GC.SuppressFinalize(this);
  10. }
  11.  
  12. protected virtual void Dispose(bool disposing)
  13. {
  14. if (!disposed)
  15. {
  16. if (disposing)
  17. {
  18. // TO DO: clean up managed objects
  19. }
  20. // TO DO: clean up unmanaged objects
  21. disposed = true;
  22. }
  23. }
  24. //At runtime C# destructor is automatically Converted to Finalize method
  25. ~MyClass()
  26. {
  27. Dispose(false);
  28. }
  29. }

Note

  1. It is always recommended to use Dispose method to clean unmanaged resources. You should not implement the Finalize method until it is extremely necessary.
  2. At runtime C#, C++ destructors are automatically Converted to Finalize method. But in VB.NET you need to override Finalize method, since it does not support destructor.
  3. You should not implement a Finalize method for managed objects, because the garbage collector cleans up managed resources automatically.
  4. A Dispose method should call the GC.SuppressFinalize() method for the object of a class which has destructor because it has already done the work to clean up the object, then it is not necessary for the garbage collector to call the object's Finalize method.
What do you think?
I hope you will enjoy the tips while programming with .NET Framework. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.