C # Study Notes -.net garbage collection mechanism

Source: Internet
Author: User

MSDN description of the garbage collection mechanism:

The. NET Framework Garbage Collector manages the memory allocation and release of applications. Every time you create an object using the new operator, the runtime allocates memory for the object from the managed heap. As long as the address space in the managed heap is available, the runtime will continue to allocate space for new objects. However, the memory is not infinitely large. Eventually, the garbage collector must recycle to release some memory. The garbage collector Optimization engine determines the best time to recycle based on the ongoing allocation. When the Garbage Collector executes the recycle action, it checks the objects that are no longer used by applications in the managed heap and performs the necessary operations to recycle the memory they occupy ."

In general, we do not know when the Garbage Collector will recycle the system garbage, because it is determined by. NET, as mentioned on MSDN:

"In most cases, the garbage collector has an advantage in determining the best time to perform a collection. However, in some situations that do not often occur, forcible reclaim can improve the performance of applications. When the amount of memory is greatly reduced at a specific point in the application code, it may be appropriate to use the GC. Collect method in this case. For example, an application may use documents that reference a large number of unmanaged resources. When your application closes this document, you are completely aware that you no longer need the resources used in the document. It makes sense to release all these resources at a time for performance reasons. For more information, see the GC. Collect method ."

In other words, under normal circumstances, we do not need to pay attention to when the Garbage Collector recycles garbage, but in some cases we need to manually call the GC. Collect Method for forced garbage collection.

Let's take a look at how Collect works. When we create a reference object, CLR will check whether there is enough space on the hosting stack, we will not allocate a memory block to store objects on the hosting stack. The objects we create are divided into two types: objects with Terminator and objects without Terminator. We will discuss them in detail later.

When the Garbage Collector determines to perform garbage collection, it will find a hosted object that is no longer in use from the managed heap. When it finds that an object has no reference pointing to it, it is deemed that the object meets the recycling conditions and is recycled. However, there are so many objects on the hosting stack. Where can I start with the garbage collector? The root concept should be introduced. The root variable is the local variable, static variable, and other variables pointing to the CPU register of the managed heap. In the process of searching, the garbage collector starts from a chain on the root, find the managed heap object referenced by the variable on the chain, add the object to a graph, and check whether the object references other objects in the managed heap. If yes, add the referenced other objects to this graph, and so on until the end of the chain, and start searching for the next chain. After all the variables on the root are traversed, objects on the managed stack that are not added to the graph are considered to be objects that meet the recycle condition and need to be recycled to release the memory.

What I just mentioned is that objects that do not implement the Finalize method are recycled. There are some differences between objects that implement the Finalize method.

Why is the Finalize method implemented?

As mentioned earlier, CLR can only manage objects in managed stacks. For unmanaged resources, CLR does not know how to handle them. When we use unmanaged resources in a class, although CLR can trace the lifecycle of these unmanaged objects, it does not know how to clear these resources. For these types of objects ,. NET Framework provides Object. the Finalize method, but the Finalize method does not perform any operations. To clear the object before the Garbage Collector recycles the object memory, you must override the Finalize method in the class.

Secondary garbage collection mechanism

The garbage collector uses an internal structure named "Terminate queue" to track objects with the Finalize method. When we create an object that implements the Finalize method, the garbage collector automatically adds an item pointing to this object to the terminate queue. When the Garbage Collector recycles the object, it only recycles the memory of the inaccessible object without the Terminator. In this case, it cannot recycle inaccessible objects with Terminator. It removes the items of these objects from the termination queue and places them in the list of objects marked as prepared for termination. The items in this list point to the object in the managed heap that is preparing to be called to terminate the code. The garbage collector calls the Finalize method for the objects in the list and then removes these items from the list. Subsequent garbage collection will determine that the terminated objects are indeed spam, because the items in the list marked as prepared to terminate objects no longer point to them. In the subsequent garbage collection, the object memory was actually recycled.

Let's look at a specific example.

Using System; class {~ A () {Console. writeLine ("Destruct instance of A");} public void F () {Console. writeLine ("A.F"); Test. refA = this ;}} class B {public A Ref ;~ B () {Console. writeLine ("Destruct instance of B"); Ref. F () ;}} class Test {public static A RefA; public static B RefB; static void Main () {RefB = new B (); RefA = new (); refB. ref = RefA; RefB = null; RefA = null; // A and B now eligible for destruction GC. collect (); GC. waitForPendingFinalizers (); // B now eligible for collection, but A is not if (RefA! = Null) Console. WriteLine ("RefA is not null"); Console. ReadKey ();}}

Run the command to check the result.

 

Public static A RefA; public static B RefB; static void Main () {RefB = new B (); RefA = new A (); RefB. ref = RefA; RefB = null; RefA = null; // A and B now eligible for destruction GC. collect (); GC. waitForPendingFinalizers (); // B now eligible for collection, but A is not if (RefA! = Null) Console. WriteLine ("RefA is not null"); RefA = null; GC. Collect (); GC. WaitForPendingFinalizers (); Console. ReadKey ();

Run:

We will find that the second garbage collection did not call the Refa destructor, because in the first garbage collection, the items of the objects referenced by Refa have been excluded from the termination queue, after waitforpendingfinalizers is executed, it is removed from the list of objects to be terminated. Therefore, the objects whose Finalize method is not implemented are recycled. refa = This; "add another sentence, GC. reregisterforfinalize (test. refa );,

Then run

 

We can see that the Refa destructor, GC. reregisterforfinalize (test. refa) is equivalent to telling the Garbage Collector that this is an object that implements the Finalize method and should be added to the terminate queue,

Why does the Garbage Collector not automatically add it to the termination queue? This is because Refa is "resurrected" here, rather than defining an object, so it will not be automatically added. What if we want to tell the Garbage Collector not to call the Refa destructor? Use GC. suppressfinalize (test. Refa) to request the system not to call the terminator of the specified object. Add GC. suppressfinalize (test. Refa) after "GC. reregisterforfinalize (test. Refa)". We will see that the Refa destructor is not called.

In fact, the garbage collection mechanism of. NET is very complicated. For example, there is also the concept of "Generation". I only have a simple understanding of garbage collection. I hope you will give me some advice and welcome to criticize and correct me!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.