Tutorials to .com

Tutorials to .com » Dotnet » Foundation » . NET's memory management, GC mechanism for the release of the process of memory

. NET's memory management, GC mechanism for the release of the process of memory

Print View , by: iSee ,Total views: 6 ,Word Count: 3579 ,Date: Tue, 21 Apr 2009 Time: 4:48 PM

Introduction as a. NET programmers, we know that managed code memory management is automatic. . NET can be managed to ensure that our procedures for all released in the end, which for our programmers to save a lot of trouble, we can not evenhow to manage memory, anyway. NET they will ensure that all. Well, right, quite true. The problem is that when we use unmanaged resources. NET can not automatically be managed. This is because the non-managed code from the CLR (Common Language Runtime) control and management beyond the scope of CLR. So how do these non-hosted resources,. NET is and how to manage the resources of this release of hosting? Automatic memory management and GC in the original proceedings of the heap memory allocation is as follows: first find there is sufficient memory address space (not occupied), and then the memory allocation. When the program no longer need this memory when the information programmers need to manually release this memory. Heap memory is common, meaning that all processes are likely to cover the contents of memory to another process, which is why many of the procedures are poorly designed and even the operating system itself will fall down. We sometimes encounter inexplicable died procedures (random phenomenon), is also inappropriate because the memory management of the (possibly as a result of the procedure itself or the memory problem caused by external procedures). Another common example is that we often see the game Trainer, they are modified by direct memory game, "Invincible" effect. Understand that we can imagine the memory address is used if the confusion of how dangerous it would, we can imagine why the c + + programmer (s), a pointer to bring the cause of the headache. In addition, if the process of memory will not be a programmer to manually release the memory, then it will not be re-distribution, re-starting the computer up to date, that is, we are talking about memory leaks. These are described in non-managed code, CLR code, through the realization of inter-AppDomain isolation to avoid the memory management issues, that is to say an AppDomain under normal circumstances can not be read / write memory of another AppDomain. Memory release hosted by the GC (Garbage Collector) is responsible for. We should further on is the GC, but before the first in this talk about managed code in memory allocation, heap memory allocation of trusteeship is the sequence, that is next to a distribution of a. This will be the speed of memory allocation process than the original high, but the rate will be higher than the GC look back. Why? GC read after work you will know the answer. GC work we need to know that managed code objects in the recovery when we(unless forced to use GC recovery GC.Collect, it is not recommended, the latter would explain why). GC will be in its "happy" when the implementation of a recovery (which a number of reasons, such as when not enough memory. This is done to increase the memory allocation, the efficiency of recovery). Well, if we do Destructor? It did not work, because. NET in the Destructor of the concept does not exist any more, it turned into a Finalizer, which will be referred back. Please keep in mind that an object is currently the only reference in the absence of any circumstances can be recovered. To illustrate this point see the following piece of code:
[C #] object objA = new object (); object objB = objA; objA = null; / / forced recovery. GC.Collect (); objB.ToString (); [Visual Basic] Dim objA As New Object () Dim objB As Object = objAobjA = Nothing 'forced recovery. GC.Collect () objB.ToString ()
ObjA here the object of reference has not been recovered, because there is another reference to this object, ObjB. In the absence of any reference object after the conditions have been recovered. When the GC recovery, it will do the following steps: identification of the object without any reference. Check whether the table in record Finalizer. Finalizer table if there are records, then moved to the other records on a table where we call it Finalizer2. Finalizer2 form if not on record, then release the memory. Finalizer2 table in the Finalizer object in a low priority on the implementation of the thread removed from the table. When the object is created when the GC will check whether the Finalizer, if Finalizer table will add a record. We are talking about here is actually a pointer record. If you carefully look at this a few steps, we will Finalizer found the object of recovery will not be the first time, that is, there are the Finalizer object to Collect more than once will be the recovery operation, it is necessary to slow step, so the authors recommend unless it is absolutely necessary not to create a Finalizer. In order to prove that GC is indeed nonsense, rather than the author, we will be resurrected in the object is given a chapter in an example, seeing is believing, hearing them for the virtual! ^ _ ^ GC in order to improve the efficiency of recovery using the concept of Generation, the principle is that the first object created before recovery is Generation 0, after each time when the recovery will be the number of the Generation of a backward move, that is, said that when the second recovery of the original Generation 0 become Generation 1, but recovered in the first and second objects created before recovery will belong to Generation 0. GC will first try of the objects belong to Generation 0 to recover, because these are the latest, so most likely will be recovered, such as some function of local variables in the exit function when not in use (can be recycled). If the Generation 0 to recover enough memory, then the GC will not be followed by a recovery, if recovery is not enough, then the GC will try to recover in the Generation 1, if not on the Recovery of Generation 2 as analogy. Generation also has a maximum limit, in accordance with the version of the framework can be used to obtain GC.MaxGeneration. In the recovery of memory after the GC will re-schedule the entire memory, so that there is no space between the data, this is because the CLR memory allocation order, so memory is not available between the memory. Now we know that each time when the recovery will be a waste of CPU time, and this is not me that the general reasons for manually GC.Collect (unless you, like me, to write some of the GC sample !^_^)。 Destructor decline, Finalizer birth for Visual Basic programmers, this is a new concept, it will focus on the first part of the C++ + + programmers. We know that in C + + in the time when the object is to remove (delete), Destructor in the implementation of the code will immediately release to do the work of a number of memory (or other). However, in. NET in the GC as a result of the special working methods, Destructor does not actually exist, in fact, when we use the syntax Destructor, the compiler will automatically write it as a protected virtual void Finalize (), this is what I said The Finalizer. As its name said, it used to end certain things, not to destroy (Destruct) things. In Visual Basic it is in the form of Finalize method, so Visual Basic programmers do not have to worry about the. Destructor programmers to use C # syntax to write Finalizer, but not to the confused,. NET has not been Destructor. C + + in that we can accurately know when will be the implementation of Destructor, however. NET, we can not know when it will implement the Finalizer, because it is the first object after the implementation of the recovery operation. We can not know Finalizer implementation of the order, that is to say the same circumstances, A's Finalize might be executed, B, after the implementation, may also after the implementation of A and B of the first implementation. In other words, the Finalizer code, we can not have any time for logic. Now we have a class to calculate the number of instances for example, pointed out that different Finalizer and Destructor also pointed out that there is time in the Finalizer logical error because Visual Basic does not have an example Destructor So only C # version:
[C #] public class CountObject (public static int Count = 0; public CountObject () (Count + +;) ~ CountObject () (Count -;)) static void Main () (CountObject obj; for (int i = 0; i <5; i + +) (obj = null; / / this step redundant, so only in order to more clearly write more! obj = new CountObject ();) / / Count is not 1, because the Finalizer will not be triggered immediately, once we have to wait until after the recovery operation will be triggered. Console.WriteLine (CountObject.Count); Console.ReadLine ();)
Note If the code above to use C + + to write, then memory leaks will happen, because we do not have to use delete operator to manually clean up the memory, but in managed code, however there will be no memory leaks, because GC will automatically detect the object not in use and recycling . Here the authors recommend that you only achieve with the use of IDisposable interface Finalizer, in other cases do not use (there may be exceptional circumstances). Resources in a non-hosted the release of a chapter, we will better understand the IDisposable interface, Jesus Now, let us do it! What is the object of the resurrection? Can also be the subject of recycling, "the revival of" it? Yes, although the definition of so inaccurate. Let us first look at a section of code:
[C #] public class Resurrection (public int Data; public Resurrection (int data) (this.Data = data;) ~ Resurrection () (Main.Instance = this;)) public class Main (public static Resurrection Instance; public static void Main () (Instance = new Resurrection (1); Instance = null; GC.Collect (); GC.WaitForPendingFinalizers (); / / see it here, "resurrection" of the. Console.WriteLine (Instance.Data); Instance = null; GC.Collect (); Console.ReadLine ();)) [Visual Basic] Public Class Resurrection Public Data As Integer Public Sub New (ByVal data As Integer) Me.Data = data End Sub Protected Overrides Sub Finalize () Main.Instance = Me MyBase.Finalize () End SubEnd ClassPublic Class Main Public Shared Instance As Resurrection Sub Main () Instance = New Resurrection (1) Instance = Nothing GC.Collect () GC . WaitForPendingFinalizers () 'see it here, "resurrection" of the. Console.WriteLine (Instance.Data) Instance = Nothing GC.Collect () Console.ReadLine () End SubEnd Class
You might well ask: "If this object can be resurrected, then this object in the program will be recovered after the end of it?." Will be, "Why?." Let us work in accordance with the GC once you go to understand how the matter. 1, the implementation of Collect. Check references. No problem, the object has been not in use. 2, create a new instance of table has been made in the Finalizer record, so we have to check the object Finalizer. 3, as found in the Finalizer, there will be recorded to form Finalizer2. 4, in the form Finalizer2 record, so I do not release memory. 5, Collect implemented. At this time we have spent GC.WaitForPendingFinalizers, so we will wait until all the Finalizer2 form Finalizers implementation. 6, Finalizer implementation we also refers to the Instance on the target of our. (Revived) 7, and then remove all references to time. 8, the implementation of Collect. Check references. No problem. 9, as a result of the last record has been deleted from the Finalizer table, so the object is not found there Finalizer. 10, in the form Finalizer2 do not exist, so the memory object has been released. Now you understand why, let me tell you, "the revival of" usefulness. Ah, this ... ... Well, I do not know. In fact, the resurrection of no use, but to do so is very dangerous. It seems that the mechanism can only be described as loopholes in GC (see GC.ReRegisterForFinalize re-use their brains would like to know why click on the flaws can be said to be a). Authors suggest that you forget what the resurrection, to avoid the use of this type. You may ask: "What you told us that they have to?" I said, it allows them to better understanding of the working mechanism of GC! ^ _ ^ The release of unmanaged resources up to now, we say that the hosting of memory management, so when we use such as databases, documents and other non-hosted resources do? At this time we will use. NET Framework standard: IDisposable interface. In accordance with the standards, there is a need to manually release all unmanaged resources have to achieve this type of interface. This interface is only one way, Dispose (), but the Guidelines relative instructions on how to achieve this interface, where I would like to talk about. IDisposable interface to achieve this type of need for such a structure:
[C #] public class Base: IDisposable (public void Dispose () (this.Dispose (true); GC.SupressFinalize (this);) protected virtual void Dispose (bool disposing) (if (disposing) (/ / Trust-type) / / release unmanaged resource) ~ Base () (this.Dispose (false);)) public class Derive: Base (protected override void Dispose (bool disposing) (if (disposing) (/ / Trust-type) / / unmanaged resources release base.Dispose (disposing);)) [Visual Basic] Public Class Base Implements IDisposable Public Overloads Sub Dispose () Implements IDisposable.Dispose Me.Dispose (True) GC.SuppressFinalize (Me) End Sub Protected Overloads Overridable Sub Dispose (ByVal disposing As Boolean) If disposing Then 'Trust Class End If' Release unmanaged resources End Sub Protected Overrides Sub Finalize () Me.Dispose (False) MyBase.Finalize () End SubEnd ClassPublic Class Derive Inherits Base Protected Overloads Overrides Sub Dispose (ByVal disposing As Boolean) If disposing Then 'Trust Class End If' Release unmanaged resources MyBase.Dispose (disposing) End SubEnd Class
Why design it this way? Let me explain you in the back. Now we talk about the Dispose method to achieve this a number of criteria: it can not throw any errors, repeat the call can not throw an error. In other words, if I have to call an object's Dispose, when I call Dispose the second time the procedure should not be wrong, simply say that the procedure call in the second Dispose will not do anything. These can be a flag to determine if the achievement or multiple. Dispose of an object to achieve the release of all the resources of this object. Take as an example of a type of succession, inheritance class unmanaged resources used by it to achieve the IDisposable interface, if the base class type of succession is also used in a non-hosted resources, then the base class have been released, the resource base class type in the inheritance release it? Of course, through a virtual / Overridable methods, so we can ensure that every call to the Dispose were. That is why we design a virtual / Overridable the Dispose method. Attention to the release of our first type of succession and then release the resources of the resource base class. Non-hosted resources to protect the right to be released so we have to define a Finalizer programmer forgot to avoid the situation to call Dispose. Above design has been adopted in this form. If we manually call the Dispose method is not necessary to retain the Finalizer, so we spent Dispose object GC.SupressFinalize removed from the Finalizer table, so that when recycling faster. So that disposing and "Trust" is how the case? Is this: in the "Trust category" write all you want to call Dispose when to release them in a state of managed code. They remember what we said we do not know what is managed code when it release? Here we only remove a member of the reference object so that it can be recovered in the state, not directly release the memory. In "Trust category" we have to write in here all the members realized the IDisposable object, because they have Dispose, and thus need to call Dispose the object of their Dispose, so as to ensure that the second criteria. is to distinguish between disposing of the call Dispose method, if we call it manually to the second criteria, "hosted" by some of the implementation of course, but if they are Finalizer calls Dispose, the object this time there are no references, that is the object members would not exist naturally (without reference), it is not necessary to the implementation of "managed" by some because they have been in a state can be recovered. Well, this is all the IDisposable interface. Let us now recall the past, we may think that memory will soon Dispose has been released, this is wrong. Only unmanaged memory will be released soon, hosted by the GC to release memory management, we do not have control. The use of weak references A = B, we call such a reference is called strong references, GC is a strong reference by checking to determine whether an object can be recovered. There is also a reference called weak references (WeakReference), this reference does not affect the GC recovery, and this is where the usefulness of it. You may ask what is the use of in the end. Now we come to the assumption that we have a target of fat, that is to say that it occupied a lot of memory. We used the object reference it intends to remove the GC so that memory can be recovered, but the effort we do not need this object, and no way to re-create examples of how to create such a? Is there any way to solve this problem? There will be the object does not remain in the memory of them soon! But we do not want to get fat plays the object of total memory, and we do not want to always create a new instance of this fat because it is very time-consuming. How to do it ... ...? Smart friends must have guessed what I wanted to say a solution is a weak reference. Yes, that is it. We are the fat can create a weak reference object, so that enough memory can be recovered when the GC does not affect memory usage, and in the GC has not been recovered before we can again make use of the object. Here's a sample:
[C #] public class Fat (public int Data; public Fat (int data) (this.Data = data;)) public class Main (public static void Main () (Fat oFat = new Fat (1); WeakReference oFatRef = new WeakReference (oFat); / / from here, Fat the object can be recovered. oFat = null; if (oFatRef.IsAlive) (Console.WriteLine (((Fat) oFatRef.Target). Data); / / 1) / / mandatory recycling. GC.Collect (); Console.WriteLine (oFatRef.IsAlive); / / False Console.ReadLine ();)) [Visual Basic] Public Class Fat Public Data As Integer Public Sub New (ByVal data As Integer) Me.Data = data End SubEnd ClassPublic Module Main Sub Main () Dim oFat As New Fat (1) Dim oFatRef As New WeakReference (oFat) 'from here, Fat the object can be recovered. oFat = Nothing If oFatRef.IsAlive Then Console.WriteLine (DirectCast (oFatRef.Target, Fat). Data) '1 End If' mandatory recycling. GC.Collect () Console.WriteLine (oFatRef.IsAlive) 'False Console.ReadLine () End SubEnd Module
Fat here is not our fat, but the original intention of the example can be: how to use weak references. Finalizer that if there is Fat, it will happen? Fat has Finalizer If so, we may use another constructor WeakReference, which has a parameter called TrackResurrection, if it is True, as long as the Fat of the memory has not been released we will be able to use it, that is to say the Finalizer implementation of Fat or we can be resumed Fat (equivalent to the first after the recovery operation may return to Fat); If TrackResurrection is False, then the recovery operation after the first Fat can not be restored on. I would like to write a summary of the articles are as follows: When an object is only referenced in the absence of any circumstances under which it will be recovered. An object of memory is not released immediately, GC at any time in its recovery. Under normal circumstances not mandatory recycling. If there are no special needs do not write Finalizer. Finalizer not have time to write some code logic. In any non-hosted resources or with members of the class Dispose achieve IDisposable interface. Dispose in accordance with the given design Dispose write their own code. When the target weight may be taken into account the use of weak references. Well, on this point, the GC would like to let you know the code more stable, more concise, more to speed up! More importantly, no longer have memory management issues, whether it is hosted or non-hosting! Reference information 1, GC Classms-help: / / MS.VSCC/MS.MSDNVS.2052/cpref/html/frlrfSystemGCClassTopic.htm2, Programming For Garbage Collectionms-help: / / MS.VSCC/MS.MSDNVS.2052/cpguide / html/cpconprogrammingessentialsforgarbagecollection.htm3, Curso de Erik, Septima Entrega (Spanish) http://guille.costasol.net/NET/cursoCSharpErik/Entrega7/Entrega7.htm About the author Author: Yuan Wei (Kefroth)


.NET foundation Articles


Can't Find What You're Looking For?


Rating: Not yet rated

Comments

No comments posted.