Mastering C# Part 1.2

Garbage Collection
Part 1.1 https://hashnode.com/post/cm3zixz1z001308lcc4h83gn2 (How C# works)
Garbage collection in C# is an automatic memory management technique used to manage memory in .NET applications. The garbage collector (GC) periodically scans memory to identify objects that are no longer in use and frees up their memory, eliminating the need for developers to manually manage memory allocation and deallocation.
Key Features of C# Garbage Collection:
Automatic Memory Management: The GC automatically handles memory allocation and deallocation, reducing the risk of memory leaks and improving developer productivity.
Low Performance Impact: Garbage collection runs in the background with minimal performance overhead, though large memory cleanups can cause brief pauses in execution.
Generation-Based Collection: The GC uses a generational approach, categorizing objects into "young" and "old" generations. Objects that survive multiple collection cycles move to the "old" generation, reducing collection time as most objects are collected in the "young" generation.
Finalization: Objects with finalizers are moved to a special finalization queue for cleanup tasks before they are destroyed by the GC.
Garbage Collection Triggers: Garbage collection occurs under various conditions:
Low physical memory: The GC runs when the system has low memory.
Memory threshold exceeded: GC is triggered when allocated memory surpasses a set threshold.
Manual invocation: The
GC.Collectmethod can be used, though it is typically called in exceptional cases.
Automatic memory management is made possible by
Garbage Collection in .NET Framework
.When a class object is created at runtime, a certain memory space is allocated to it in the heap memory. However, after all the actions related to the object are completed in the program, the memory space allocated to it is a waste as it cannot be used. In this case, garbage collection is very useful as it automatically releases the memory space after it is no longer required. Garbage collection will always work on
Managed Heap and internally it has an Engine which is known as the Optimization Engine.
Garbage Collection Phases in C#
Marking Phase: In this phase, the garbage collector identifies all the live objects by following references from root objects. Any object not marked as live is considered for deletion.
Relocating Phase: During this phase, the references to the live objects are updated so that they point to their new locations in memory. This ensures that the objects are correctly referenced after they are moved.
Compacting Phase: The heap is compacted by moving the live objects towards the older end of the heap, releasing space previously occupied by dead objects. This helps optimize memory usage by reducing fragmentation.
Heap Generations in Garbage Collection
In C#, the heap memory is divided into three generations to optimize garbage collection based on the lifespan of objects:
Generation 0: This generation holds short-lived objects, like temporary variables. Most new objects are allocated here unless they are large. Garbage collection runs most frequently in Generation 0, as these objects typically have a short lifespan.
Generation 1: If some objects from Generation 0 survive the garbage collection, they are promoted to Generation 1. This generation acts as a buffer between short-lived Generation 0 objects and long-lived objects in Generation 2.
Generation 2: If objects from Generation 1 survive multiple garbage collections, they are promoted to Generation 2. This generation typically holds long-lived objects, such as static objects, which remain in memory for the entire duration of the program.
Key Points:
Garbage Collection Flow: When a garbage collection occurs for a generation, all younger generations (i.e., lower numbered generations) are also collected. For example, when Generation 2 is garbage collected, Generation 1 and Generation 0 are also cleaned up.
Full Garbage Collection: A garbage collection of Generation 2 is a "full" garbage collection because it cleans all generations in the heap.
Memory Allocation: Memory allocated to Generation 2 is larger than that of Generation 1, and Generation 1 is larger than Generation 0 (Generation 2 > Generation 1 > Generation 0).
Example:
The GC.MaxGeneration property can be used to demonstrate the number of generations in the heap during garbage collection.
public static void Main(string[] args)
{
Console.WriteLine("The number of generations are: "
+ GC.MaxGeneration);
}
Methods in GC Class
GC.GetGeneration() Method: This method returns the generation number of the target object. It requires a single parameter i.e. the target object for which the generation number is required.
using System;
public class Demo {
public static void Main(string[] args)
{
Demo obj = new Demo();
Console.WriteLine(
"The generation number of object obj is: "
+ GC.GetGeneration(obj));
}
}
GC.GetTotalMemory() Method: This method returns the number of bytes that are allocated in the system. It requires a single boolean parameter where true means that the method waits for the occurrence of garbage collection before returning and false means the opposite.
using System;
public class Demo {
public static void Main(string[] args)
{
Console.WriteLine("Total Memory:"
+ GC.GetTotalMemory(false));
Demo obj = new Demo();
Console.WriteLine(
"The generation number of object obj is: "
+ GC.GetGeneration(obj));
Console.WriteLine("Total Memory:"
+ GC.GetTotalMemory(false));
}
}
//Total Memory:4197120
//The generation number of object obj is: 0
//Total Memory:4204024
GC.Collect() Method : Garbage collection can be forced in the system using the GC.Collect() method. This method requires a single parameter i.e. number of the oldest generation for which garbage collection occurs.
using System;
public class Demo {
public static void Main(string[] args)
{
GC.Collect(0);
Console.WriteLine(
"Garbage Collection in Generation 0 is: "
+ GC.CollectionCount(0));
}
}
//Garbage Collection in Generation 0 is: 1
