. NET garbage collection-Principle Analysis
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 an object in C #. We can use the new keyword to create an object of the reference type, for example, 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, programmers don't have to worry about when the object will be 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 grid newobj command in the implementation of the method. below is the IL code seen through ILSpy. IL_0001: newobj instance void GCTest. student ::. in fact, the newobj Command tells CLR to execute the following operations: calculate the total memory required for the new object and check the managed heap, make sure there is sufficient space to store the new object. If there is sufficient space, 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 not enough, an OutofMemoryException will be reported). Finally, move NextObjPtr to the next available address of the managed heap, 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. 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 to by NextObjPtr exceeds the address space of the managed heap, and a garbage collection is required, the garbage collector deletes the root Garbage Collector of an inaccessible object application from the managed heap. How does one 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 of local objects in the application code library passed into a method the reference of object parameters is waiting to be terminated (finalize, will be introduced later) the CPU register garbage collection of any referenced object can be divided into two steps: Mark the object compression managed heap and combine the concept of the application root. Let's take a look at the two steps of garbage collection. During the garbage collection process, the garbage collector considers all objects in the managed heap as garbage, and then checks all the root objects. 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): When A root references object A in the managed heap, the garbage collector will mark this object A. After detecting A root, it will then detect the next root and perform the same marking process as step B. When marking object B, if another object E is referenced in object B, the E is also marked. Because E references G, the same method G is marked as repeating step 2, check the Globales root. This tag Object D code may reference the same object E in multiple objects. As long as the Garbage Collector detects that the object E has been marked, then, it no longer checks the objects referenced in Object E. This method 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. In the example above, 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 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: 0: the first generation of newly assigned objects not marked as recycled: in the previous garbage collection, there were no recycled objects in generation 2: for objects that have not been recycled after more than one garbage collection, let's take an example to look at this concept (gray indicates an inaccessible object): During program initialization, there is no object on the managed stack, at this time, the generation of the newly added objects on the managed stack is 0, and these objects have never been checked by the garbage collector. Assuming that there are seven A-G objects on the managed heap, the managed heap space will be exhausted. If more managed heap space is needed to store new objects (H, I, J), CLR triggers a garbage collection. The garbage collector will check all the 0-generation objects, and all the inaccessible objects will be cleared. All the objects not recycled will become the 1-generation objects. Assuming that more managed heap space is needed to store new objects (K, L, and M), CLR will trigger garbage collection again. The garbage collector checks all the 0-generation objects first, but still requires more space. The Garbage Collector will continue to check all the 1-generation objects and sort out enough space. At this time, the first generation object that has not been recycled will become the second generation object. The second-generation object is currently the highest generation of the garbage collector. When garbage collection is performed again, the algebra of objects not recycled remains 2. 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. The System. GC. NET Class Library provides the System. GC type. Some static methods of this type can be programmed to interact with the garbage collector. Let's take 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 () ;}} from this output, we can also verify the concept of generation. After each spam, 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 garbage manager, we do not need to care about the destruction of objects on the managed stack and the collection of memory space. However, in some special cases, we may need to use GC. collect () Forced garbage collection: the application is about to enter a piece of code, which does not want to be interrupted by possible garbage collection. The application has just been allocated a lot of objects, when the program wants to recycle memory space as soon as possible after these objects are used, it is recommended to 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.