Managed heap memory management policy and garbage collection
The managed heap stores the objects in sequence, and carries out memory sorting after garbage collection. Therefore, if GC occurs frequently, the system performance will be reduced because GC cleans up the memory, causing the object to move in the memory, applications on CLR before GC endsProgramIt is impossible to continue running. net uses the generation garbage collector. The memory management policy on CLR is similar to the memory management policy of OS (CLR itself is a virtual machine ).
1. CLR Memory Management
The CLR managed heap stores the objects in the memory in sequence. If a new memory request exists, it will traverse the managed heap and find the first continuous memory space meeting the requirements, save the object in this space.
Assume that the CLR starts addressing from a storage block with a memory of 4001 (it is unknown whether the CLR uses a paging system, so it can only be described using a storage block, at this time, you need to allocate a memory of 2 units to the new object, the CLR will traverse from top to bottom, find-continuous space available, save the new object in this continuous space.
2. Garbage collection and memory sorting
, GC will scan its managed heap to check whether there are any referenced objects. For example, when GC is run, the reference of object 1 has been removed, mark 4003, and memory blocks in the maintained memory table as not occupied, and GC will sort the managed memory.
In fact, the clr gc collector is a generation recycler: CLR divides the memory of its managed heap into multiple generations, starting from the 0th generation, all newly applied objects will be allocated to the memory space of The 0th generation. If a GC recycle occurs on the 0th generation, or the 0th-generation memory space is insufficient (a GC recycle will be triggered at this time). After GC recycle is completed, the CLR, compress and store the remaining objects on the 0th generation to the next generation (1st generation), and so on. The existing objects on the 1st generation will be moved to the 2nd generation ....
In this way, CLR actually ensures that the objects on the 0th generation are the latest objects, and the objects stored in the larger the generation space should be the older objects, generally, the latest object is the most frequently modified object, so GC is the most efficient on The 0th generation, and memory movement is faster.
Collection of unmanaged Resources
1. destructor
In the destructor, it identifies the unmanaged resources that the object should release when it is released,CodeSimilar
ClassMyclass
{
~ Myclass ()
{
//Releases unmanaged resources, such as database connections, files, networks, and streams.
}
}
Disadvantages of using destructor:
1. CLR cannot guarantee when the GC will be executed. That is to say, the unmanaged resources will not be released immediately after the object is useless, but need to wait for the GC to run.
2. GC does not actually release unmanaged resources when calling the Destructor for the first time, but actually releases unmanaged resources when calling the second call.
3. CLR uses an independent thread to call all the destructor. If too many resources are released, the execution efficiency of the thread will be seriously affected.
2. idisponse Interface
The idisponse interface supports the C # language level. When using an object that implements the idispone interface, you can use using to automatically release its managed resources (equivalent to try. finally statement block). Its usage is as follows:
ClassMyclass: idisponse
{
Public VoidDisponse ()
{
//Release unmanaged Resources
}
}
ClassUseclass
{
Using(Myclass =NewMyclass ())
{
//Use myclass
}
}
Disadvantages of using idisponse
Idispone is too dependent on people's calls. If you forget to use using or display the call during software development, the unmanaged resources cannot be effectively released.
3. Comprehensive
By using the above two methods, we can get a better result. The code is similar
Public Myclass: idispose
{
Private Void Isdisposed = False ; // Record whether the resource has been released
// Implementation of idispone
Public Void Dispose ()
{
Dispose ( True );
GC. suppressfinallize ( This ); // The destructor of the current class no longer need to be called when GC is executed
}
Protected Virtual Void Disponse ( Bool Disposing)
{
If (! Isdisposed)
{
If (Disposing)
{
// You can release some managed resources when using dispose,
// If the GC has been executed when the Destructor is called, the managed resources cannot be guaranteed to have been released, so it is best not to release the managed resources.
// Call the dispose method of managed resources to release their resources (managed & unmanaged)
}
// Release unmanaged resources (disconnect databases, close streams, etc)
}
Isdisponsed = True ;
}
~ Myclass
{
Dispose ( False );
}
// Generally, all methods of this class should include the judgment on isdispose.
Public Void Somemethod ()
{
If (Isdispose)
{
Throw New Objectdisposedexception ();
}
// Implementation of methods
}
}