. Net garbage collection-Principle Analysis and. net garbage collection
This article cited from: http://www.cnblogs.com/wilber2013/p/4357910.html
During the development of. NET programs, since the garbage collection mechanism in CLR manages allocated objects, programmers can ignore the time when objects are released. However, it is necessary to understand the garbage collection mechanism. Let's take a look at the related content of the. NET garbage collection mechanism.
Create object
In C #, we can use the new keyword to create a reference type object, such as the following statement. The New Keyword creates a Student type object. The newly created object will be stored in the managed heap, and the reference of this object will be stored in the call stack. (You can view the reference type, C # value type and reference type)
Student s1 = new Student();
In C #, after the Student object is created, the programmer does not have to worry about when the object is destroyed. The Garbage Collector will destroy the object when it is no longer needed.
After a process is initialized, the CLR retains a continuous memory space. This continuous memory space is what we call the managed heap .. The. NET Garbage Collector manages and cleans up the hosted heap. It compresses the empty memory block as necessary to optimize it. To assist the Garbage Collector in this row, the managed heap stores a pointer, which is exactly the location where the next object will be allocated, called the next object pointer (NextObjPtr ). To introduce the garbage collection mechanism below, let's take a closer look at what the new Keyword has done.
New Keyword
When the C # compiler encounters the new Keyword, it will add a command in the implementation of the method, the following is the IL code seen through ILSpy.
IL_0001: newobj instance void GCTest.Student::.ctor()
In fact, the newobj Command tells CLR to perform the following operations:
- Calculate the total memory size required for the new object.
- Check the managed heap to make sure there is sufficient space to store new objects.
- If the space is sufficient, call the Type constructor to store the object in the memory address pointed to by NextObjPtr.
- If there is not enough space, a garbage collection will be executed to clear the managed heap (if the space is still insufficient, an OutofMemoryException will be reported)
- Finally, move NextObjPtr to the next available address of the managed heap, and then return the object reference to the caller.
According to the above analysis, when we create two Student objects, the managed heap should be consistent, and NextObjPtr points to the new available address of the managed heap.
The size of the managed heap is not unlimited. If we keep using the new keyword to create new objects, the managed heap may be exhausted, in this case, the managed heap can detect that the space pointed by NextObjPtr exceeds the address space of the managed heap, and a garbage collection is required. The Garbage Collector will delete inaccessible objects from the managed heap.
Application Root
How does the Garbage Collector determine that an object is no longer needed and can be safely destroyed?
Here we will look at the concept of an application root. Root is a storage location where reference to an object on the managed heap is stored. The root can attribute any of the following categories:
- Reference of global and static objects
- References to local objects in the application code library
- References to object parameters passed into a method
- Wait for finalize (described later) Object Reference
- CPU registers of any referenced objects
Garbage collection can be divided into two steps:
Next we will take a look at the two steps of garbage collection based on the concept of application root.
Mark object
In the process of garbage collection, the garbage collector will think that all objects in the managed heap are garbage, and then the Garbage Collector will check all the roots. To this end, CLR creates an object graph, representing all reachable objects on the managed stack.
Assuming that the managed heap has seven A-G objects, the garbage collector checks all objects for active root during garbage collection. The garbage collection process in this example can be described as follows (gray indicates inaccessible objects ):
In the code, it is very likely that multiple objects reference the same object E. As long as the Garbage Collector detects that object E has been marked, it will not detect the objects referenced in Object E,This has two purposes: improving performance and avoiding infinite Loops.
After all the root objects are checked, the marked object is the reachable object, and the unmarked object is the inaccessible object.
Compressed hosting heap
In the above example, the garbage collector will destroy all unlabeled objects, release the memory occupied by these junk objects, and then move the reachable objects here to compress the heap.
Note: After moving reachable objects, all variables that reference these objects will be invalid, and the garbage collector will re-traverse all the roots of the application to modify their references. In this process, if each thread is executing, it is likely that the variable is referenced to an invalid object address. Therefore, the thread of the entire process that is executing the managed code is suspended.
After garbage collection, all non-spam objects are moved together, And the pointers of all non-spam objects are modified to the memory address after moving, nextObjPtr points to the end of the last Non-spam object.
Object generation
When the CLR tries to find an inaccessible object, it needs to traverse the objects hosted on the stack. As the program continues to run, the managed heap may become larger and larger. If garbage collection is required for the entire managed heap, it will inevitably seriously affect the performance. Therefore, in order to optimize this process, the CLR uses the concept of "generation". Every object on the hosting stack is specified to belong to a "generation" (generation ).
The basic idea of "Generation" is that the longer an object exists on the managed stack, the more likely it should be retained. Objects in the managed heap can be divided into three generations: 0, 1, and 2:
- Generation 0: never marked as recycled new objects
- Generation 1: objects not recycled in the previous garbage collection
- Generation 2: objects not recycled after more than one garbage collection
Here is an example of the concept of generation (gray represents an inaccessible object ):
The preceding description shows that generation division can avoid traversing the entire managed heap for each garbage collection, which can improve the performance of garbage collection.
System. GC
The. NET Class Library provides the System. GC type. Some static methods of this type can interact with the garbage collector through programming.
Let's look at a simple example:
class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Estimated bytes on heap: {0}", GC.GetTotalMemory(false));
Console.WriteLine("This OS has {0} object generations", GC.MaxGeneration);
Student s = new Student { Id = 1, Name = "Will", Age = 28, Gender = "Male"};
Console.WriteLine(s.ToString());
Console.WriteLine("Generation of s is: {0}", GC.GetGeneration(s));
GC.Collect();
Console.WriteLine("Generation of s is: {0}", GC.GetGeneration(s));
GC.Collect();
Console.WriteLine("Generation of s is: {0}", GC.GetGeneration(s));
Console.Read();
}
}
Program output:
From this output, we can also verify the concept of generation. After each garbage cleanup, if an object is not cleared, its generation will be improved.
Forced garbage collection
Because the objects on the managed Stack are managed by the spam manager, we do not need to care about the destruction of the objects on the managed stack and the collection of memory space.
However, in some special cases, we may need to force garbage collection through GC. Collect:
We recommend that you call "GC. waitForPendingFinalizers (); ", which determines that all the terminable objects must be purged before the program continues. However, you must note that GC. WaitForPendingFinalizers () suspends the calling thread during the recycle process.
static void Main(string[] args)
{
……
GC.Collect();
GC.WaitForPendingFinalizers();
……
}
Every garbage collection process will consume performance, so we should try to avoid forced garbage collection through GC. Collect () unless it is necessary to implement forced garbage collection.
Summary
This article introduces. the basic working process of the. NET garbage collection mechanism. The Garbage Collector marks the objects on the managed stack by traversing them, and then clears all inaccessible objects. The objects on the managed Stack are set as a generation, through the concept of generation, the performance of garbage collection has been optimized.