. NET Framework Automatic Memory Management Mechanism in-depth analysis (C # Analysis)

Source: Internet
Author: User
Source: http://www.eqccd.com/ServiceSupport/view.asp? Id = 182 & kind = 13
In. in the. NET Framework, resources in the memory (that is, the set of all binary information) are divided into "managed resources" and "unmanaged resources ". managed resources must be accepted.. NET Framework (Common Language Runtime) management (such as memory type security check), rather than hosting resources do not have to accept.. NET Framework. (For more information, see. NET Framework or C # advanced programming materials)

Managed resources are stored in. NET Framework is stored in two places: "stack" and "managed heap" (hereinafter referred to as "Heap"). The rule is, all value types (including references and object instances) and reference types are stored in the "stack", and all object instances represented by references are stored in the heap.

In C #, the release of managed resources can be automatically completed through the "Garbage Collector" (note that the "Garbage Collection" mechanism is. NET Framework, rather than C #), but specifically, there are still some points to note:
1. the value type (including reference and object instances) and reference type references do not need any "Garbage Collector" to release the memory, because when they are out of scope, the occupied memory will be automatically released (because they are all stored in the "stack", we have learned the data structure that shows this is an advanced and later structure );
2. only the object instances referenced by reference types are stored in the "Heap". Because the heap is a free storage space, therefore, it does not have a life period like the "stack" (after the "stack" element pops up, it indicates that the life period ends and the memory is released, the "Garbage Collector" only applies to this area;
3. the "Garbage Collector" may not be executed immediately as many people think (when the resources in the heap need to be released ), but there is an interval between the deletion of a reference type reference and the deletion of its object instance in the "Heap". Why? Because the call to the "Garbage Collector" consumes system resources, it is impossible to be called frequently!

(Of course, the user code can use the method System. GC. Collect () to force the "Garbage Collector ")

However, in most cases, we need to release managed resources explicitly without executing the "Garbage Collector" (because only a part of resources need to be released but they need to be released very much, but it is best not to call the "Garbage Collector", because "Garbage Collector" is too wasteful of system resources), or to release "unmanaged resources", what should we do at this time? This is an issue we must consider when writing code (the "Garbage Collector" is automatically implemented by the system and generally does not require user intervention ), otherwise, the Windows system will exhaust the memory...
Now, let me tell you how to release all types of resources and use the Dispose () method of the class to release unmanaged resources!
1. Dispose () method
To release resources using the Dispose () method, execute "System. IDisposable "interface, and then the class must contain the defined method" void Dispose () "(in the Dispose () method, it is the code segment written by the user to release resources ), in this way, you will know that you can manually call the Dispose () method to release resources. note that the "Garbage Collector" does not call the Dispose () method to release managed resources!

2. destructor
The format for defining the destructor in C # is "~ CLASS_NAME ()". note that if an unmanaged resource is not used in a class, do not define the Destructor because the object executes the destructor, therefore, the "Garbage Collector" must call the Destructor before releasing managed resources, and then release the managed resources for the second time. In this way, the cost of the two Delete actions is more than that of the first action! (However, even if you have defined the destructor in the class, there is still a way to "Block" it, which will be described in the code example below) in the Destructor method, it is a code segment written by the user to release unmanaged resources.

The following code demonstrates how to use the Dispose () method and destructor:

Public class ResourceHolder: System. IDisposable
{
Public void Dispose ()
{
Dispose (true );
System. GC. SuppressFinalize (this );
// The above line of code prevents the "Garbage Collector" from calling methods in this class
//"~ ResourceHolder ()"
// Why do you want to prevent it? Because if you remember to call the Dispose () method
// "The Garbage Collector" does not need to "let alone" Release the "unmanaged resources" again.
// If the user does not remember to call it, let the "Garbage Collector" help us to "do more" ^_^
// It doesn't matter if you don't understand what I said above. I have more details here!

}

Protected virtual void Dispose (bool disposing)
{
If (disposing)
{
// Here is the user code segment for clearing "managed resources"
}
// Here is the user code segment for clearing "unmanaged resources"
}

~ ResourceHolder ()
{
Dispose (false );
}
}

The above code is a typical class definition with two Dispose methods.
There are many System Classes in. NET Framework that use this method to define the Dispose () method, for example:
In MSDN, The System. Drawing. Brush. Dispose method is defined as follows:
**************************************** ********************
* Release all resources used by this Brush object. *
* Public void Dispose ()*
* This Member supports the. NET Framework Structure, so it is not applicable to use directly from the code. *
* Protected virtual void Dispose (bool );*
**************************************** ********************

Here, we must be clear that the user needs to call the method Dispose () instead of the method Dispose (bool). However, the method that actually executes the release is not Dispose (), instead, it is Dispose (bool )! Why? Take a closer look at the Code. In Dispose (), Dispose (true) is called. When the parameter is "true", it is used to clear all managed and unmanaged resources; you must remember that as I said before, "using the Destructor is used to release unmanaged resources", since Dispose () can release unmanaged resources, what else do I need to analyze the constructor? In fact, the role of the Destructor is only a "backup "!
Why?
Strictly speaking, if the class that executes the interface "IDisposable", as long as the programmer uses the object instance of this class in the Code, he must call the Dispose () method of this class sooner or later, at the same time, if the class contains the use of unmanaged resources, you must also release the unmanaged resources! Unfortunately, if the code for releasing unmanaged resources is put in the Destructor (The above example corresponds "~ ResourceHolder () "), it is impossible for the programmer to call this release code (because the Destructor cannot be called by the user and can only be called by the system, specifically the" Garbage Collector ), therefore, you should know why the "user code segment for clearing unmanaged resources" in the above example is in Dispose (bool), rather ~ ResourceHolder () in! Unfortunately, not all programmers always remember to call the Dispose () method. If the programmer forgets to call this method, it is okay to host resources, in the morning and evening, there will be a "Garbage Collector" to recycle (but it will be postponed for a while). What about unmanaged resources? It is not controlled by CLR! Can the unmanaged resources it occupies never be released? Of course not! We also have the "destructor! If you forget to call Dispose (), the "Garbage Collector" will also call the "destructor" to release unmanaged resources! (If the programmer remembers to call Dispose (), then the code "System. GC. suppressFinalize (this); "prevents the" Garbage Collector "from calling the destructor, so that you do not have to release" unmanaged resources "one more time) so we are not afraid that programmers will forget to call the Dispose () method.
So I have said a lot of reasons, and there are only two points in combination:
* 1. programmers should never forget to call the Dispose () method! (If any, ^_^)
* 2. If you forget it, don't worry... Save it !!! Because there is also the "Garbage Collector" to help us automatically call the Destructor!

Related Article

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.