In the. NET Framework, resources in memory, which is a collection of all binary information, are categorized as managed resources and unmanaged resources. Managed resources must accept the management of the. NET Framework's CLR (Common language Runtime), such as memory type security checks, while unmanaged resources do not have to accept the CLR management of the. NET Framework. (See the. NET Framework or advanced programming materials for C # for more information) managed resources reside in two places in the. NET Framework: "Stacks" and "managed Heaps" (hereinafter referred to as "heaps"); The rule is that all value types (including references and object instances) and reference types are stored in the stack, and all references represent instances of the objects that are stored in the heap. In C #, freeing a managed resource can be done automatically through the garbage collector (note that the "garbage collection" mechanism is a feature of the. NET Framework, not C #), but there are still some things to keep in mind: 1, value types (including references and object instances) and reference type references actually do not need a "garbage collector" to free up memory, because when they go out of scope will automatically free up the occupied memory (because they are stored in the "stack", learn the data structure is an advanced post-out structure); 2. Only the object instance to which the reference type reference refers to is saved in the Heap ", and because the heap is a free storage space, it does not have a lifetime like" stack "(the" stack "element pops up to the end of the lifetime, which represents the release of memory), and it is important to note that the" garbage collector "only works on this area; 3," Garbage collector " It may not be immediately executed (when a resource in the heap needs to be released), but rather as a reference to a reference type is removed and it has an interval in the middle of the object instance being deleted in the heap. Because the "garbage collector" calls are relatively consuming system resources, it is not always possible to be called! (Of course, user code can use method System.GC.Collect () to enforce the "garbage collector") However, in most cases, we need to explicitly release the managed resources without executing the garbage collector (because only some of the resources that need to be freed are released, But what if we don't call the garbage collector because the garbage collector is too wasteful of system resources, or need to release unmanaged resources? This is what we have to consider when writing code (the "garbage collector" is automatically implemented by the system, the general situation does not require user intervention), or the Windows system because of memory exhaustion and so on ... Now, let me tell you what to do, which is to use the Dispose () method of the class to release allType resources and use the Destructor method to release unmanaged Resources! 1. The Dispose () method releases the resource through the Dispose () method, then the "System.IDisposable" interface is used when the class is defined and must contain the method defined in the class "void Dispose ()" (in the Dispose () Method is the code snippet that the user writes to release the resource, so the user knows that the resource can be freed by invoking the Dispose () method artificially. However, it is important to note that the garbage collector does not release managed resources by calling the Dispose () Method! 2, the Destructor method defines the destructor method in C # in the format "~class_name ()". It is important to note that if an unmanaged resource is not used in a class, you must not define a destructor because the object performs a destructor, and the garbage collector calls the destructor before releasing the managed resource, and then the second time actually releases the managed resource, Two delete actions are more expensive than once! (However, even if you already have a destructor defined in your class, there is still a way to "mask" it, as explained in the following code example), in the Destructor method, the code snippet that the user wrote to release the unmanaged resource. Here's a piece of code to demonstrate how the Dispose () method and the Destructor method use:
public class resourceholder:system.idisposable { public void Dispose () { dispose (True); system.gc.suppressfinalize (This); //the previous line of code is to prevent the garbage collector from calling methods in this class //"~resourceholder ()" Why should //prevent it? Because if the user remembers to call the Dispose () method, then the //"garbage collector" is not necessary "Superfluous" to release again "Unmanaged Resources" //if the user does not remember to call it, let " Garbage collector "Help us go to the superfluous," ^_^ //you.Do not understand what I said above does not matter, below I also have a more detailed explanation! } protected virtual void Dispose (bool disposing) { if (disposing) { //here is the user code snippet to clean up "managed resources" } //here is the user code snippet to clean up "unmanaged resources" } ~resourceholder () { dispose (false); } The above code is a typical two-DThe class definition of the Ispose method. There are many system classes in the. NET Framework that define the Dispose () method in this way, for example: in MSDN, the System.Drawing.Brush.Dispose method is defined as: ********************* Releases all resources used by this Brush object. ** public void Dispose () ** this member supports the. NET framework structure and is therefore not intended to be used directly from your code. * * protected virtual void Dispose (BOOL); ************************************************************* Here, we have to be clear that the user is required to call the method Dispose () instead of the method Dispose (bool), however, the method that actually performs the release work here is not Dispose (), but Dispose (bool)! Why? Look closely at the code, in Dispose (), call Dispose (true), and the argument is "true" when the function is to clean up all managed and unmanaged resources;Remember before I said, "The use of destructors is used to release unmanaged resources," So now that Dispose () can be done to release the work of unmanaged resources, but also how to do the destructor? In fact, the function of the destructor is only a "backup"! Why is it? Strictly speaking, where the class that executes the interface "IDisposable", so long as the programmer in the code to use the object instance of this class, then sooner or later call this class's Dispose () method, at the same time, if the class contains the use of unmanaged resources, you must also release the unmanaged Resources! Unfortunately, if the code that frees the unmanaged resource is placed in the destructor (the example above corresponds to "~resourceholder ()"), then it is impossible for the programmer to invoke the release code (because the destructor cannot be called by the user, but only by the system, which is called the "garbage Collector"). So you should know why the "user code snippet to clean unmanaged resources" in the example above is in Dispose (bool), not ~resourceholder ()! Unfortunately, not all programmers are always careful to call the Dispose () method, in case the programmer forgets to call this method, the managed resource is certainly no problem, sooner or later there will be a "garbage collector" to recycle (just a little later), then unmanaged resources? It is not under the control of the CLR! is it that the unmanaged resources it occupies will never be released? Of course not! We also have a "destructor"! If you forget to call Dispose (), the garbage collector also calls the Destructor method to release the unmanaged Resources! (Say a little more nonsense, if the programmer remembers calling Dispose (), then code System.GC.SuppressFinalize (this) prevents the garbage collector from invoking the destructor so that it does not have to release the unmanaged resource more than once.) So we're not afraid of programmers forgetting to call the Dispose () method. So I said a lot of reasons, mixed up only two points: * 1, the program staff Ah, do not forget to call the Dispose () Method! (If any ^_^) * *, in case you forget, don't worry ... Also Saved!!! Because there are "garbage collector" to help us automatically call the destructor Method!
C # Memory managed heap vs. unmanaged heap (reprint)