Garbage recycling programming in .NET

zhaozj2021-02-17  51

The .NET framework garbage collector management application memory allocation and release. Each time you use the New operator to create an object, the running library allocates memory from the managed pile to the object. As long as there is address space available in the hosted stack, the runtime will continue to assign space for the new object. However, memory is not unlimited. In the end, the garbage collector must perform recycling to release some memory. The garbage collector optimization engine determines the best time to perform recycling according to the on-allocation situation. When the garbage collector performs recycling, it checks the objects that are no longer used by the application and perform the necessary operations in the hosted stack to recover their occupied memory.

Developers in memory management

Depending on your development background, your experience in memory management will also be different. In some cases, you may need to make your program habit to adapt to the automatic memory management provided by the public language runtime.

COM developer

COM developers are accustomed to implementing a reference count as a manual memory management technology. Each time you reference an object, the counter is incremented. If the reference to the object is exceeded, the counter is decremented. When the reference count of the object reaches zero, the object is terminated and released.

The reference counting scheme will trigger a lot of debugging errors. If it is not possible to operate strictly according to the rules of the reference count, the object may be released prematurely or not referenced in memory. Cycle reference is also a common problem root. Cycle references appear in sub-objects to reference parent objects, while parent objects are referenced by sub-objects. This situation makes two objects that cannot be released or destroyed. The only solution is to let the parent objects and sub-objects comply with a fixed usage and destruction mode, such as deleting sub-objects first by parent objects.

When developing an application using a hosted language, the garbage collector of the run library eliminates the need to count the reference, so an error caused by this manual management memory scheme is avoided.

C developer

C developers are familiar with tasks related to manual memory management. In C , you must use the delete operator to release the memory of the object using the DELETE operator when you use the New Operator to assign memory. This can cause multiple errors, such as forgetting to release objects, causing memory leaks or attempting to access memory that has been released.

You do not have to use the Delete operator to release the object using the Delete operator when developing an application using a C managed extension or other hosting language. The garbage collector automatically completes these operations when the object is no longer used by the application.

C developers may be accustomed to avoiding using these objects, taking into account the related costs of manual management of short-term objects. The cost of hosted short-term objects, allocation, and release memory created between the two recovery is then used. In the .NET framework, the garbage collector has been optimized to manage objects with shorter survival. When developing a hosted application, it is very appropriate to use them in the case of simplifying the code.

Visual Basic Developer

Visual Basic developers are accustomed to automatic memory management. Your familiar programming practice will be applied to most managed objects you created in the .NET framework. However, when creating or using an object of encapsulating a non-hosting resource, you should pay special attention to the recommended design pattern of the Dispose method.

The hostage language supported by the .NET framework is much more than the point introduced here. No matter which kind of hosted language you use, the garbage collector of the .NET framework provides automatic memory management. It assigns and releases memory for managed objects, and performs the Finalize method and the destructor when necessary to properly clean up the non-hosting resources. Automatic memory management simplifies development by eliminating common problems caused by manual memory management scheme.

Finalize method and destructor

Most objects created for your application, you can rely on the accessible memory management task to the garbage collector of the .NET framework. However, when you create an object of the encapsulated unmanaged resource, you must explicitly release them after using these unmanaged resources in your application. The most common type of unmanaged resource is an object of packaging operating system resources, such as files, windows, or network connections. Although the garbage collector can track the survival of the object of the unmanaged resource, it does not understand how to clean these resources. For these types of objects, the .NET framework provides an Object.Finalize method, which allows objects to properly clean their unmanaged resources when the garbage collector is recycled. By default, the Finalize method does not perform any operations. If you want the garbage collector to perform cleanup operations to the object before recycling objects, you must rewrite the Finalize method in the class. When developing programming languages ​​other than C # and C managed, you can implement a Finalize method. C # and hosted extensions provide destructor as a simplified mechanism for writing termination code. The destructor automatically generates the Finalize method and the call to the base class. In C # and hosted extension programming languages, you must use the analyzable syntax for termination code. The garbage collector tracks an object with a Finalize method using an internal structure called "Target Queue". Each time your application creates an object with a Finalize method, the garbage collector places an item that points to the object in the termination queue. All objects that need to call their termination code before the garbage collector recycled their memory, contain items in the termination queue.

Implementing a Finalize method or destructuring function may have a negative impact on performance, so it should be avoided unnecessarily use them. The memory used by the Finalize method is used to recover the memory needs to be recycled at least two garbage. When the garbage collector performs recycling, it only reclaims memory of the unacceptable object without the termination. At this time, it cannot recover the irrevacular objects with a terminator. It is changed to remove these objects from the termination queue and placed them in the list of objects labeled as the termination. The items in this list point to the hosted stacks are prepared to call their termination code. A special runtime thread began in an active state and calls the Finalize method of the object in the list, and then removes these items from the list. Later garbage recycling will determine the object of the termination is indeed garbage, as items in the list of tabular objects are no longer pointing them. In the subsequent garbage collection, the memory of the object is actually recovered.

Clean up unmanaged resources

By limiting the scope of the object to protected, you can prevent the application's user from directly calling the Finalize method of the object. In addition, we strongly recommend that you do not call the Finalize method for non-base classes from the application code. To properly dispose of unmanaged resources, it is recommended that you implement a common DISPOSE or Close method, which performs the necessary object cleanup code. The IDisposable interface provides Dispose Method for resource classes for implementing interfaces. Because the Dispose method is public, the user can directly call the method directly to release the memory occupied by the non-hosting resource. If the Dispose method is properly implemented, the Finalize method (or the destructive function or C managed extension in C #) becomes a protective measures to clear the resource without calling the Dispose method.

Implement Dispose method [C #]

Type DISPOSE method should release all resources it owns. It should also release all the resources owned by the base type by calling its parent type DISPOSE method. The parent type DISPOSE method should release all resources it owns and also call the DISPOSE method of its parent type, thereby propagating this mode in the entire base type hierarchy. To ensure that resources are always properly cleaned, the Dispose method should be able to be used multiple secure calls without causing any exceptions.

The Dispose method should call the GC.SUPPRESSFINALIZE method for the object it disposed. If the object is currently in the termination queue, GC.SuppressFinalize prevents its Finalize method from being called. Keep in mind that the Finalize method will be executed. If your Dispose method has completed the work of the cleaning object, the garbage collector does not have to call the Finalize method of the object. The following code example is intended to illustrate a possible design pattern that implements the DISPOSE method for encapsulating the category of unmanaged resources. Because this mode is implemented throughout the .NET framework, you may find it very easy to use. However, this is not the only possible implementation of the Dispose method.

Resource class is usually derived from complex native or API and must be customized. Using this code mode as a starting point for creating a resource class and provides the necessary customizations according to the resource of the package. This example cannot be compiled, or it cannot be used directly for the application.

In this example, the base class baseresource implements a public DISPOSE method that can be called by a user. This method also calls the Virtual Disposing method (virtual Dispose in Visual Basic (as a Boolean value disposed)). Transfer TRUE or FALSE based on the caller's identity. Perform the appropriate cleanup code with the virtual Dispose method.

Dispose (BOOL Disposing) is performed in two distinctive programs. If the result is true, the method has been directly called or indirectly called by the user's code, and can be disposed of hosted resources and non-hosting resources. If the result is false, the method has been called inside the terminator from the runner and can only dispose of the unmanaged resources. Since the terminator does not execute in any particular order, other objects should not be referenced when the object is executing its termination code. If the terminal being executed references another object that has been terminated, the terminal executable terminal will fail.

The Finalize method or descent function provided by the base class acts as a protective measures in the absence of invoking dispose. The Finalize method calls the DISPOSE method with parameters and transmits FALSE. The Dispose cleaning code should not be recreated within the finalize method. Call Dispose (false) can optimize the readability and maintainability of the code.

Class MyResourceWrapper explains how to use Dispose from the class to manage the resource management. MyResourceWrapper Rewinds the Virtual Disposing method and provides cleaning code for managed and unmanaged resources created. MyResourceWrapper also calls Dispose for its base class baseresource to ensure that the base class can be properly cleaned. Note that derived class MyResourceWrapper does not have a Finalize method or Dispose method without parameters, as these two methods inherit them from base class baseresource.

[Visual Basic]

'Design Pattern for the base class.

'By Implementing IDisposable, you are announce instances

'of this Type Allocate Scarce Resources.

Public Class Baseresource

Implements idisposable

'Pointer to an External UNMANAGED RESOURCE.

Private Handle As Intptr

'Other Managed Resource this Class Uses.

Private Components As Component 'Track WHETHER DISPOSE HAS BEEN CALLED.

Private disposed as boolean = false

'Constructor for the baseresource object.

Public Sub New ()

'INSERT Appropriate Constructionor Code Here.

End Sub

'Implement Idisposable.

'Do not make this method overridable.

'A Derived Class Should Not Be Aable To Override this Method.

Overloads Public Sub Dispose () IMPLEments Idisposable.dispose

Dispose (True)

'Take Yourself Off of The Finalization Queue

'To Prevent Finalization Code for this Object

'from executing a second.

Gc.suppressFinalize (ME)

End Sub

'Dispose (Disposing as boolean) Executes in Two Distinct Scenarios.

'If disposing is true, The Method Has Been Called Directly

'or indirectly by a user's code. Managed and unmanaged resources

'can be disposed.

'If disposing equals false, The method Has Been Called by the runtime

'from inside the firmizer and you shouth not reason other

'Objects. Only unmanaged resources can be de disposed.

Overloads Protected Overridable Sub Dispose (Disposing as Boolean)

'Check To See if Dispose Has Already Been Called.

If not (me.disposed) THEN

'If disposing equals true, Dispose All Managed

'and unmanaged resources.

IF (Disposing) THEN

'Dispose Managed Resources.

Components.dispose ()

END IF

'Release Unmanaged Resources. If Disposing is False,

'Only The Following Code Is Executed.

CloseHandle (Handle)

Handle = INTPTR.ZERO

'Note That this is not thread safe.

'Another Thread Could Start Disposing The Object

'after the managed resources area disposed,

'but before the disposed flag is set to true.

END IF

Me.Disposed = truend sub

'This finalize method will run inly if The

'Dispose Method Does Not get Called.

'By Default, Methods Are NotOverridable.

'This prevents a derived class from overriding this method.

Overrides protected sub firmize ()

'Do Not Re-Create Dispose Clean-Up Code Here.

'Calling Dispose (False) Is Optimal in Terms of

'Readability and Maintainability.

Dispose (False)

End Sub

'Allow Your Dispose Method to Be Called Multiple Times,

'But throw an exception if the object has been disposed.

'WHENEVER You do Something with this class,

'Check to see if it has been disposed.

Public Sub Dosomething ()

If me.disposed then

Throw new ObjectdisposedException ()

END IF

End Sub

END CLASS

'Design Pattern for a Derived Class.

'Note That Derived Class Inherently Implements

'Idisposable Interface Because IT IT ITEMENTED IN THE BASE CLASS.

Public Class MyResourceWrapper

Inherits Baseresource

'A managed resource That you add in this dermid class.

Private AddedManaged As ManagedResource

'A Native Unmanaged Resource That You Add in this derived class.

Private Addednative As NativeATIVERESOSOTIVE

'Track WHETHER DISPOSE HAS Been Called.

Private disposed as boolean = false

'Constructor for the MyResourceWrapper Object.

Public Sub New ()

Mybase.new ()

'INSERT Appropriate Constructionor Code Here for T

'Added Resources.

End Sub

Protected Overloads Overides Sub Dispose (Disposing as Boolean)

If not (me.disposed) THEN

Try

IF Disposing then

'Release The Managed Resources You Added in

'this derived class here.

AddedManaged.dispose ()

END IF

'Release The Native Unmanaged Resources You Added' In this Derived Class Here.

CloseHandle (Addednative)

Me.disposed = true

Finally

'Call Dispose on your base class.

Mybase.dispose (Disposing)

END TRY

END IF

End Sub

END CLASS

'This Derived Class Does Not Have A Finalize Method

'or a dispose method without parameters becault it

'Inherits the.' 'in.

[C #]

// Design Pattern for the base class.

// by Implementing IDisposable, you are announce set instances

// of this Type Allocate Scarce Resources.

Public Class Baseresource: IDisposable

{

// Pointer to an External UNMANAGED RESOURCE.

Private INTPTR HANDLE;

// Other managed resource this class uses.

PRIVATECIENTS;

// TRACK WHETHER DISPOSE HAS Been Called.

PRIVATE BOOL DISPOSED = FALSE

// Constructor for the baseresource object.

Public Baseresource ()

{

// INSERT Appropriate Constructor Code Here.

}

//Mplement idisposable.

// do not make this method.

// a Derived Class Should Not Be Aable To Override this Method.

Public void dispose ()

{

Dispose (TRUE);

// Take Yourself Off of the Finalization Queue

// TO Prevent Finalization Code for this Object

// from executing a second time.

Gc.suppressFinalize (this);

}

// Dispose (Bool Disposing) Executes in Two Distinct Scenarios.

// if disposing equals true, The Method Has Been Called Directly

// or indirectly by a user's code. management and unmanaged resources

// can be disposed.

// if disposing equals false, The method Has been Called by The Method Has

// Runtime from inside the firmizer and you shouth not reason

// Other Objects. Only Unmanaged Resources Can Be disposed.

Protected Virtual Void Dispose (BOOL Disposing)

{

// Check to See if Dispose Has Already Been Called.

IF (! this.disposed)

{

// if disposing equals true, dispose all managed

// and unmanaged resources.

IF (Disposing)

{

// Dispose Managed Resources.

Components.dispose ();

}

// Release unmanaged resources. If disposing is false,

// ONLY The FOLLOWING CODE IS EXECUTED.

CloseHandle (Handle);

Handle = INTPTR.ZERO;

// Note That this is not thread Safe.

// Another Thread Could Start Disposing The Object

// after the managed resources area disposed,

// But Before the disposed flag is set to true.

}

Disposed = true;

}

// Use C # Destructor Syntax for Finalization Code.

// this Destructor Will Run Only If The dispose Method

// DOES Not get Called.

// IT Gives Your base class the Opportunity to Finalize.

// Do Not Provide Destructors in Types Derived from this class.

~ Baseresource ()

{

// Do Not Re-Create Dispose Clean-Up Code Here.

// Calling Dispose (False) Is Optimal in Terms of

// readability and maintainability.

Dispose (false);

}

// allow your dispose method to be caled multiple times,

// But throw an exception if the object has been disposed.

// WHENEVER You do Something with this class,

// Check to see if it has been disposed.

Public void dosomething ()

{

IF (this.disposed)

{

Throw new ObjectdisposedException ();

}

}

}

// Design Pattern for a Derived Class.

// Note That tris derived class inherently imports the

// Idisposable Interface Because It is used in the base class.

Public Class MyResourceWrapper: Baseresource

{

// a managed resource That You Add in this deive Class.

Private managedresource addedmanaged;

// a native unmanaged resource That You Add in this derived class.

Private NativeResource Addednative;

PRIVATE BOOL DISPOSED = FALSE

// Constructor for this Object.

Public myResourceWrapper ()

{

// INSERT Appropriate Constructor Code Here.

}

Protected Override Void Dispose (Bool Disposing)

{

IF (! this.disposed)

{

Try

{

IF (Disposing)

{

// Release The Managed Resources You Added in

// this derived class here.

AddedManaged.dispose ();

}

// Release the native unmanaged resources you added

// in this deact class here.

CloseHandle (Addednative);

THISPOSED = TRUE;

}

Finally

{

// Call Dispose on your base class.

Base.dispose (Disposing);

}

}

}

}

// this Derived Class Does Not Have a finalize Method

// OR a dispose method with parameters because it inherits

// Them from the base class.

Implement a Close method

For types, if the CLOSE method is more easier than calling the Dispose method, you can add a public CLOSE method to the base type. The close method also calls the DISPOSE method without parameters, which can perform the correct cleaning operation. The following code example illustrates the Close method.

[Visual Basic]

'Do not make this method overridable.

'A derived class shop not be unloaded

'TO Override this Method.

Public Sub Close ()

'Calls The Dispose Method WITHOUT Parameters.

Dispose ()

End Sub

[C #]

// do not make this method.

// a derived class shop not be unloaded

// TO OVERRIDE this Method.

Public void close ()

{

// Calls The dispose method without parameters.

Dispose ();

}

Rewrite Finalize method

The Finalize method is not allowed to clean up resources in the event of an unable to call the Dispose method. You should only implement the Finalize method to clean up the unmanaged resources. You should not implement a Finalize method for managed objects because the garbage collector automatically cleans up managed resources. By default, the Object.Finalize method does not perform anything. You must rewrite this method in the class if you want the garbage collector to perform cleanup operations to the object before the memory of the object is recycled.

Note You cannot rewrite the Finalize method in a C # or C hosted extension programming language. You must use the destructor syntax provided by these languages ​​as a mechanism to write termination code.

The range of Object.Finalize method is protected. You should maintain this limited range when rewriting the method in the class. By protecting the Finalize method, you can prevent the application's Finalize method directly calls the object.

The Finalize method of the object should release all resources retained by the object. It should also call the Finalize method of the object base class. The Finalize method of the object does not respond to any non-base class object call method. This is because other objects called may be recovered at the same time at the same time, such as the public language runtime. If you allow any exception to avoid the Finalize method, the system will consider the method to return and continue to call the Finalize method for other objects.

Destructor syntax using C # and C hosted extensions

In C # or C hosted extension programming languages, you cannot call or rewrite the Object.Finalize method. C # and hosted extensions provide destructor as a mechanism to write termination code. In C # and hosted extensions, you must use the patterned syntax to perform the cleaning operation. Since the syntax is implicitly invoke the Finalize method for the object base class, it is easy to use. This ensures that Finalize is called for all levels of the current class from it from its export.

The following code example is written for the destructor.

~ Myclass ()

{

// Perform Some Cleanup Operations Here.

}

This code is implicitly translated into the following code.

Protected Override Void Finalize ()

{

Try

{

// Perform Some Cleanup Operations Here.

}

Finally

{

Base.Finalize ();

}

}

Note Although they look similar, the C # and hosted extension destructor have different semantics from the non-hosting C destructor. The hosted code does not support any semantics similar to the C destructor.

Objects using package resources

When writing the code of the object to the encapsulation, you should make sure the Dispose method of the object is called when the object is used. You can use the C # USING statement or implement the TRY / FINALLY block in other managed languages.

C # Using statement

C # programming language Using statements are automatically called by simplifying the code you must write to create and cleaning objects. The using statement gets one or more resources, performs the statements you specify, and then dispose of the object. Note that the USING statement is only used for objects that do not exceed the method of building an object in the survival period. The following code example creates an instance of the ResourceWrapper class, as shown in the C # example of the DISPOSE method.

Class myapp

{

Public static void main ()

{

Using (resourceWrapper r1 = new resourceWrapper ())

{

// do sometying with the object.

R1.DOSMETHING ();

}

}

}

The above code is equivalent to the code of the USING statement.

Class myapp

{

Public static void main ()

{

ResourceWrapper r1 = new resourceWrapper ();

Try

{

// do sometying with the object.

R1.DOSMETHING ();

}

Finally

{

// Check for a null resource.

IF (r1! = null)

// Call The Object's Dispose Method.

r1.dispose ();

}

}

}

The USING statement of the C # allows you to get multiple resources in a single statement, which is equivalent to the internally nested USING statement. For more information and code examples, see the 8.13 Using Statement section in the C # Language Reference.

TRY / FINALLY block

When you write a managed code of an object using the package resource in a language other than the C #, use the TRY / FINALLY block to ensure that the Dispose method of the object is called. The following code example creates and cleales an instance of the Resource class, as shown in the Visual Basic example of the DISPOSE method. Class myapp

Public Shared Sub Main ()

Resource r1 = new resource ()

Try

'Do something with the object.

R1.DOSMETHING ()

Finally

'Check for a null resource.

IF not (r1 is nothing) THEN

'Call The Object's Dispose Method.

R1.dispose ()

END IF

END TRY

End Sub

END CLASS

Forced garbage collection

Garbage Recycling GC class provides gc.collect methods, you can use this method to allow applications to directly control the garbage collector to a certain extent. Typically, you should avoid calling any recycling method, allowing the garbage collector to run independently. In most cases, the garbage collector is more advantageous in determining the best time to perform recycling. However, for some uncommonly occurring, forced recycling can improve the performance of the application. When the amount of memory used in a certain point in the application code is largely reduced, in this case it may be appropriate to use the gc.collect method. For example, an application may use a document that references a large number of unmanaged resources. When your application turns off the document, you fully know that there is no longer needed to use resources. For performance, all releases these resources are meaningful. For more information, see the gc.collect method.

It will hang all threads currently executing before the garbage collector performs recycling. This may cause performance issues if you don't have to call GC.COLLECT multiple times. You should also be aware that you should not place the code that calls GC.COLLECT in the program. Users can regularly call. This may impair the role of the optimization engine in the garbage collector, and the garbage collector can determine the best time to run garbage recovery.

to sum up

The above is some concepts and little examples of garbage collection and processing in the .NET framework, give you a reference. If you have any suggestions, please Mil I Paulni@citiz.net.

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

New Post(0)