GC, garbage collect, Chinese meaning is garbage collection, refers to the distribution and recovery management of memory in the system. Its impact on system performance cannot be underestimated. Let's talk about GC optimization today. Here we will not focus on concepts and theories, but mainly on practical things. Here is a brief description of concepts and theories. For details, refer to the official Microsoft documentation.
1. What is GC?
GC, as its name is, is garbage collection. Of course, this is only for memory. Garbage Collector (Garbage Collector, which also becomes GC without confusion) uses the root of the application to traverse all objects dynamically allocated by the application on heap [2], identify whether they are referenced to determine which objects are dead and which still need to be used. The object that is no longer referenced by the root of the application or another object is the dead object, that is, the so-called garbage, which needs to be recycled. This is how GC works. To achieve this principle, GC has multiple algorithms. Common algorithms include reference counting, Mark sweep, and copy collection. Currently, the mainstream virtual systems. Net CLR, Java Vm and rotor both adopt the mark sweep algorithm. (The content is from the network)
The gc mechanism of. Net has two problems:
First, GC does not release all resources. It cannot automatically release unmanaged resources.
Second, GC is not real-time, which will cause bottlenecks and uncertainties in system performance.
GC is not real-time, which may cause bottlenecks and uncertainty in system performance. With the idisposable interface, the idisposable interface defines the dispose method, which is used by programmers to explicitly call to release unmanaged resources. You can use using statements to simplify resource management.
Ii. managed and unmanaged Resources
Managed resources refer to. net resources that can be automatically recycled, mainly the memory resources allocated on the managed stack. The collection of managed resources does not require manual intervention. Some. Net runtime Libraries call the Garbage Collector to recycle the resources.
Unmanaged resources refer. net does not know how to recycle resources. The most common type of unmanaged resources are the objects that encapsulate operating system resources, such as files, windows, network connections, database connections, image brushes, and icons. This type of resource, the garbage collector will call the object. Finalize () method during cleaning. By default, the method is empty. For unmanaged objects, you need to write code to recycle unmanaged resources in this method so that the garbage collector can correctly Recycle resources.
In. net, object. the finalize () method cannot be overloaded. The Compiler automatically generates an object based on the class destructor. the finalize () method. Therefore, for classes that contain unmanaged resources, you can place the code that releases the unmanaged Resources in the destructor.
Iii. Example of GC Optimization
Under normal circumstances, we don't need to worry about GC. However, GC is not real-time, so when GC is recycled after our resources are used up is not certain, therefore, there will be some situations such as memory leakage and insufficient memory. For example, if we process a large file of about MB, GC will not immediately execute cleanup to release the memory after it is used up, GC does not know whether it will be used again, so it waits. It first processes other things. After a while, it finds that these things are no longer used before cleaning and releasing the memory.
Below, we will introduce several functions used in GC:
GC. suppressfinalize (this); // do not call the terminator of the specified object when requesting the public language runtime.
GC. gettotalmemory (false); // retrieves the number of bytes currently considered to be allocated. A parameter that indicates whether the method can wait for a short interval before returning, so that the system can recycle garbage and terminate objects.
GC. Collect (); // force instant garbage collection for all generations.
GC Operating Mechanism
Before writing code, let's talk about the GC running mechanism. As we all know, GC is a background thread that periodically searches for objects and calls the finalize () method to consume them. We inherit the idispose interface, call the dispose method, and destroy the objects, GC does not know. GC still calls the finalize () method, but in. net, the object. Finalize () method cannot be overloaded, so we can use the destructor to prevent repeated releases. After calling the dispose method, we also call the GC. suppressfinalize (this) method to tell GC that the finalize () method of these objects does not need to be called.
Next, we will create a console program and add a factory class to let it inherit from the idispose interface. The Code is as follows:
Using system; using system. collections. generic; using system. LINQ; using system. text; namespace garbagecollect {public class factory: idisposable {private stringbuilder sb = new stringbuilder (); List <int> List = new list <int> (); // concatenate a string, create some memory spam public void makesomegarbage () {for (INT I = 0; I <50000; I ++) {sb. append (I. tostring () ;}// when the class is destroyed, the Destructor ~ Factory () {dispose (false);} public void dispose () {dispose (true);} protected virtual void dispose (bool disposing) {If (! Disposing) {return;} sb = NULL; GC. Collect (); GC. suppressfinalize (this );}}}
The Using statement can be used only when the class is inherited from the idispose interface. Write the following code in the main method:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Diagnostics;namespace GarbageCollect{ class Program { static void Main(string[] args) { using(Factory f = new Factory()) { f.MakeSomeGarbage(); Console.WriteLine("Total memory is {0} KBs.", GC.GetTotalMemory(false) / 1024); } Console.WriteLine("After GC total memory is {0} KBs.", GC.GetTotalMemory(false) / 1024); Console.Read(); } }}
The running result is as follows. We can see that the memory usage after the resource runs the makesomegarbage () function is 1796kb, and then 83kb.
Code Running Mechanism:
We have written the dispose method and the destructor. When will they be called? We break points on the two methods respectively. After debugging and running, you will find that you have gone to the dispose method first, knowing that the program is not running the destructor, because we have called GC. suppressfinalize (this) method. If this method is removed, you will find that the first dispose method is followed by the destructor. Therefore, we can know that if we call the dispose method, GC will call the destructor to destroy the object and release the resource.
4. When should I call GC. Collect?
In order to let everyone see the effect, I will display the called GC. the collect () method allows GC to immediately release memory, but GC is frequently called. the collect () method reduces program performance unless some operations in our program occupy a large amount of memory and need to be released immediately to display the call. The descriptions in the official documentation are as follows:
The garbage collection GC class provides the GC. Collect method, which allows applications to directly control the Garbage Collector to a certain extent. In general, you should avoid calling any recycling method so that the garbage collector can run independently. In most cases, the garbage collector is more advantageous in determining the best time to execute a collection. However, in some situations that do not often occur, forcible reclaim can improve the performance of applications. When the amount of memory is greatly reduced at a specific point in the application code, it may be appropriate to use the GC. Collect method in this case. For example, an application may use documents that reference a large number of unmanaged resources. When your application closes this document, you are completely aware that you no longer need the resources used in the document. It makes sense to release all these resources at a time for performance reasons. For more information, see the GC. Collect method.
Before the Garbage Collector executes collection, it suspends all threads currently being executed. If you call GC. Collect multiple times without having to do so, this may cause performance problems. You should also be careful not to place the code that calls GC. Collect on the point that users can call frequently in the program. This may weaken the engine optimization function in the garbage collector, and the garbage collector can determine the best time to run garbage collection.
References: http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface
Mining performance optimization schemes from the C # garbage collection (GC) Mechanism