To understand the C # garbage collection mechanism, let's first talk about the CLR (Common Language Runtime when a Common Language is running). It is a Runtime environment like a Java Virtual Machine. Its core functions include: memory Management, assembly loading, security, asynchronous processing, and thread synchronization.
CTS (Common Type System) generic Type System, which divides. Net into two categories: reference Type and value Type .. All types in. Net are indirectly or directly derived to the System. Object type. All value types are subclasses of System. ValueType, while System. ValueType itself is a reference type.
Managed resources:
Managed resources exist on the managed stack managed by CLR. Note that there are two key points: the first is the management by CLR, and the second is the management stack. The collection of managed resources does not require manual intervention. The CLR will call the GC (Garbage Collector) to recycle resources when appropriate.
Unmanaged resources:
Unmanaged resources cannot be managed by CLR, such as Image Socket, StreamWriter, Timer, Tooltip, file handle, GDI resource, database connection, and other resources (Here we only list several commonly used resources ). These resources are not automatically recycled by GC and need to be manually released.
Through the above summary, first, GC (Garbage Collector) only recycles managed resources, not unmanaged resources. Second, GC collection is performed only when appropriate (the CLR thinks it should be recycled. So how can we recycle unmanaged data? Let me come here one by one.
There are two main ways to release unmanaged resources in. Net: Dispose and Finalize.
The Dispose method. If an object inherits the IDisposable interface, the Dispose method is automatically called.
Copy codeThe Code is as follows: Class Suifeng: System. IDisposable
{
# Region IDisposable Member
Public void Dispose ()
{
//
}
# Endregion
}
Suifeng suiFeng = new Suifeng ();
SuiFeng. Dispose ();
// You can also use the Using statement
(Using Suifeng suiFeng = new Suifeng ())
{
//
}
Finalize () method
The definition on MSDN is to allow objects to try to release resources and perform other cleanup operations before "Garbage Collection.
It is essentially a destructor.
Copy codeThe Code is as follows: class Car
{
~ Car () // destructor
{
// Cleanup statements...
}
}
The Destructor implicitly calls Finalize to the object's base class. In this way, the previous destructor code is implicitly converted to the following code:
Copy codeThe Code is as follows: protected override void Finalize ()
{
Try
{
// Cleanup statements...
}
Finally
{
Base. Finalize ();
}
}
In. NET, you should use the destructor to release resources as little as possible. In MSDN2, there is a saying like this:
The implementation of Finalize methods or destructor may have a negative impact on performance, so you should avoid unnecessary use of them. The Finalize method is used to reclaim the memory used by objects. At least two garbage collections are required. When the Garbage Collector recycles objects, it only recycles the memory of inaccessible objects without the Terminator. In this case, it cannot recycle inaccessible objects with Terminator. It removes the items of these objects from the termination queue and places them in the list of objects marked as prepared for termination. The items in this list point to the object in the managed heap that is preparing to be called to terminate the code. The garbage collector calls the Finalize method for the objects in the list and then removes these items from the list. Subsequent garbage collection will determine that the terminated objects are indeed spam, because the items in the list marked as prepared to terminate objects no longer point to them. In the subsequent garbage collection, the object memory was actually recycled.
Therefore, the object with destructor needs to be called twice. The first time the Destructor is called, the second time the object is deleted. In addition, a large amount of resource code is included in the destructor, which will reduce the efficiency of the garbage collector and affect the performance. Therefore, for objects that contain unmanaged resources, it is best to call the Dispose () method in time to recycle resources, rather than relying on the garbage collector.
In a class that contains unmanaged resources, the standard practices for resource release are as follows:
Inherit the IDisposable interface;
Implement the Dispose () method, release managed and unmanaged resources, and remove the object from the garbage collector (the garbage collector does not recycle this resource );
Implements class destructor to release unmanaged resources.
Please refer to the source code on MSDN
Copy codeThe Code is as follows: Public class BaseResource: IDisposable
{
PrivateIntPtr handle; // handle, which belongs to an unmanaged Resource
PrivateComponet comp; // component, hosting Resources
Privateboo isDisposed = false; // indicates whether the resource has been released.
PublicBaseResource
{
}
// Interface Implementation Method
// The class user calls the class externally and releases the class resources.
Public void Dispose ()
{
Dispose (true); // release managed and unmanaged Resources
// Remove the object from the linked list of the garbage collector,
// When the garbage collector is working, only managed resources are released without executing the destructor of this object.
GC. SuppressFinalize (this );
}
// Called by the garbage collector to release unmanaged Resources
~ BaseResource ()
{
Dispose (false); // release unmanaged Resources
}
// If the parameter is true, all resources are released and can only be called by users.
// If the parameter is set to false, the resources are released and can only be automatically called by the garbage collector.
// If the subclass has its own unmanaged resources, you can reload this function to add the release of its own unmanaged resources.
// But remember, to overload this function, you must ensure that the base class version is called to ensure the normal release of the base class resources.
Protectedvirtual void Dispose (bool disposing)
{
If (! This. disposed) // If the resource is not released, this judgment is mainly used to prevent objects from being released multiple times.
{
If (disposing)
{
Comp. Dispose (); // release managed resources
}
CloseHandle (handle); // releases unmanaged Resources
Handle = IntPtr. Zero;
}
This. disposed = true; // identifies that this object has been released
}
}