Pour garbage art

xiaoxiao2021-03-06  45

Some people say that the program is life. In fact, this sentence is really not over. In life, the creation of items is full of items -> Use -> Abandoning the process; in the code of the program, it is also full of objects of the object -> Use -> The process of destruction. Isn't this?

Introduction to the inquiry in the printing in the program is also in the same motivation: Each object takes up a certain space of memory. When an object is used, if it is still like it, it is not like it. In C , all created objects must be destroyed by yourself, if you don't do it, you will cause the sport to leak. It is greatly increasing that the programmer's own efficiency is increased by the programmer's own operation, but the programmer is overwhelmed. Therefore, most of the new generation of object-oriented languages ​​use the Lifetime Management technology, which is the technique that determines when the system will not be used again. In this article, let's take a look at the survival management technology in Visual Basic .NET. The vulgar said, that is, the art of pouring garbage.

Before discussing the garbage collection mechanism in .NET, let's take a look at the garbage collection technology in the Visual Basic 6 era. In the age of COM, when an object is created, it calculates how many clients will be referenced by themselves. Once it is desperate, it has been found that there is no one to quote itself, and it has no reluctance to himself, and the memory it occupies naturally returns to the memory. This garbage collection mechanism is called a reference count.

However, the survival management mechanism under the .NET Framework is different. In the CLR, the memory manager (in fact, the Garbage Collector, the famous garbage collection, below, we call it directly with GC!) ​​Master a pointer to idle memory. When you need to create an object application space, a copy of a pointer will be returned, and the pointer will finger down one position as required by the size of the memory. As long as the memory stack is still not used, the occupied memory will not be recycled until the program runs. Hey, this way of distributing memory is really efficient! In theory, the efficiency of C is alive.

However, memory is always running. If there is a need to apply for memory, GC will be busy looking for recyclable resources. The working principle of GC is a very deep topic, 淌 淌 想 想 话 话 话 话 话 话 话 话The GC is actually a very low level thread under the .NET Framework, it can check the variables containing object references (very intuitive - if an object can be obtained by the program's variable, then this object is being used) and put it) They are maintained in a finalization queue; in addition, GC also needs to know that there is no reference to other objects in these objects (that is, verifying without loop reference). Through the above method, the GC can determine all the memory being used and combine them into a neighbor block on the start of the heap to reach the purpose of recycling resources.

You may ask me, do you have any progress compared to this garbage recycling mechanism and VB6? Well, first, the reference count mechanism is unconditionally requires more system overhead; secondly, the reference count is probably the leakage of the GC, and again, the process of the GC is more concise than the reference count than the reference.

Understand the truth above, we can take a little more, let's take a look at these two typical methods: Finalize () and Dispose (). The art of pouring garbage is concentrated here.

Finalize () literal means end. It is a method of recovering non-hosting resources provided by .NET Framework (the hosted resource is automatically recovered by GC). Non-hosting resources, simply, in addition to any resource outside of memory, such as database connections, form handles, file streams, etc. The System.Object type contains the finalize () method, but the shrimp is not done. VB.NET allows Finalize () in the derived class (but hosted C and C # in principle not covered!). GC calls it on this class when the instance is recovered. Here is a very simple example: public class myclass protected overrides sub firmize () 'Note: VB.NET and C destructor's destructive function mechanism slightly' VB.NET must explicitly call the base class Finalize () method MyBase.Finalize () End Subend Class The Finalize () method must call the Finalize () method of the base class to release any resources allocated by the base class code. Of course, if this class is directly derived from the Object class, it is impossible to ignore (the Finalize () method of the Object class is not dry) - but, still develop a habit! What is wrong with this sentence? In fact, Finalize () is a destructor in VB.NET, but there is still a little difference with the C destructor. The C destructor can automatically call the destructor of its base class, but VB.NET is not! So, this is the reason for my mother-in-law to emphasize my mother-in-law.

The garbage recycling mechanism and the finalize () method seem to be enough for all the work, but they still have a defect. Because the object in the garbage collection system is destroyed when garbage recovery or application is terminated, such a mechanism is also called unaprising end (Although the reference count of VB6 is low, it is determined to end). Non-deterministic ends will bring some hidden issues: such as an object with scarce resources (database connection is typical), if you do not release resources immediately, the program may be exhausted before Take out these resources. Therefore, we need a solution that can replace the unsatisfactory determine the parsing function to end when referring to the non-hosting resource.

Dispose () Fortunately, there is always some smart people who have been inspired from C , preparing the IDisposable interface, providing objects to the non-hosting resource. If your class implements this interface, you must only implement one of them: Dispose (). Dispose literally means disposal, this method does not have a parameter, nor has returned values. This method CLR is not yet, and can only be called by customers of the object. Calling the dispose () means that this object is no longer needed, it must immediately release all the non-hosting resources posted by it unconditionally (in fact release managed resources).

The writer of the class must implement the idisposable.dispose interface, and the class customers must be very clear when calling it. However, it is harder that the customer will not ignore the call, so the writer of the class must prepare for both hands - i.e., still need to provide a Finalize () method of the class, in the internal call of this method () method. For example, the following is a relatively simple Finalize / Dispose garbage collection program: public sub dispose () imports idisposable.dispose 'Add release resource code End Subprotace Overrides Sub femalize ()' Multi-Torked once does not bring any side effects, but hey ... dispose () mybase.finalize () end sub

But the above code has a hidden dangers just avoided, because the order of the target destruction is uncertain. If the object has a reference to other objects (belonging to the hosted resource), and the GC may have reclaimed those objects, then call the Dispose () method on the reclaimed object will trigger ObjectDisposedException Exception.

Therefore, it is necessary to separate the processing of the hosted resource separately. Here is a slightly improved version, let's take a look: Public Sub Dispose () Implements IDisposable.dispose DisposeManagedResources () DisposeunManagedResources () end subsembrace

Protected Overrides sub firmize () 'finalize () only releases the non-hosting resource', so don't worry about calling dispose () DisposeunaNagedResources () Dispose.Finalize () end sub

PRIVATE SUB DISPOSEMANAGEDRESOURES () 'Add Release The code END SUB

Private Sub DisposeunManagedResources () 'Add Release Universal Size Code End Sub

The customer calls the Dispose () method, but GC does not know about it. Objects that have been called Dispose () methods still exist in the end queue of GC maintenance, that is, this object is destroyed by the customer, GC is still stupid to repeat the sect of this object. Not only does any effect, but also increases the system overhead. So, we should then optimize the Dispose method. 'It enables GC to remove an object from the GC's end queue' this to avoid the repeated election of the object GC.SuppressFinalize (ME) End Sub

Don't know so much, do you understand? In order to make the netizens better understand, I jumped too much details (maybe I'm also skipping some very important I can't realize). Now, 淌 gives a relatively complete version of garbage collection method, leave you reference!

Public Class Myclass Implements Idisposable

'This variable mark object has been disposed of private isdisposed as boolean = false' to continue adding the constructor of the global variable '...' class you need, you can improve it public sub new (...) .. End Sub

'This method is left to the customer to call this class' release all managed and unmanaged resources Public Sub Dispose () Implements IDisposable.Dispose If Not isDisposed Then DisposeManagedResources () DisposeUnmanagedResources () GC.SuppressFinalize (Me) isDisposed = True End If End Sub

'If the customer forgot to call the dispose () method', the Finalize () method is called Finalize () method by the GC to release the non-hosting resource protected overrides Sub femalize () DisposeunManagedResources () MyBase.Finalize () end sub

PRIVATE SUB DISPOSEMANAGEDRESOURES () 'Add Release The code END SUB

Private Sub DisposeunManagedResources () 'Add Release Universal Size Code End Sub

Private sub DOSMETHING () 'When you want to access the object,' needs to confirm whether the object has been disposed of AssertNotdisposed () end Sub

Private sub askespertnotDisposed () 'If the object has been disposed, an exception if isdisposed the throw _ new objectddisposedException (me.gettype (). Name) End Sub

END CLASS

how about it? It's really doctors in pouring garbage!

转载请注明原文地址:https://www.9cbs.com/read-65895.html

New Post(0)