The garbage collection mechanism automatically reclaims resources for us (the garbage collector calls finalizers automatically), so why should we voluntarily release resources?
private void Buttonopen_click (Object Sender,eventargs e) {FileStream FileStream = new FileStream (@ "C:\test.txt", Filemod E.open); } private void Buttongc_click (Object Sender,eventargs e) {System.GC.Collect (); }
This is an example of a WinForm form program in which, in this example, clicking a button is responsible for opening a file, and clicking the other button is responsible for recycling the garbage that says "generation" (the concept of generation will be detailed below). If you click the Open File button twice in a row, the system will get an error:
IOException: The file "C:\test.txt" is being used by another process, so the process cannot access the file.
If you click the Open File button and then click the Cleanup button, it works fine.
Now to analyze: In the method of opening the file, after the method executes, because the local variable FileStream in the program has no place to reference, so it will be run in the next garbage collection is marked as garbage. So, when will the next garbage collection take place, the latter saying when does the garbage collector start to actually recycle? Microsoft's official explanation is that garbage collection will occur when one of the following conditions is met:
- The system has low physical memory.
- The memory used by an allocated object on the managed heap exceeds an acceptable threshold. This means that the acceptable memory usage threshold has exceeded the managed heap. As the process runs, this threshold is continuously adjusted.
- Call the GC. Collect method. In almost all cases, you do not have to call this method because the garbage collector continues to run. This method is mainly used for special cases and tests.
Not releasing resources in a timely manner is a great waste of the system, and this waste can also interfere with the normal operation of the program (as in this case, because it always occupies the file resources, so that we can not use the file resources again).
If the type itself inherits the IDisposable interface, the garbage collection mechanism will automatically help us release the resources, but the process is extended because it does not do all the cleanup work in a single collection. In this case, because FileStream inherits the IDisposable interface, the garbage collector calls the FileStream terminator the first time it is garbage collected, and then waits for the next garbage collection, when the FileStream object can be actually recycled.
Let's improve this program:
private void Buttonopen_click (Object Sender,eventargs e) { FileStream FileStream = new FileStream (@ "C:\test.txt", FileMode.Open); Filestream.dispose (); }
But if the first line of code is abnormal, it will never execute filsstream.dispose (). Improve again:
private void Buttonopen_click (Object Sender,eventargs e) { try { FileStream FileStream = new FileStream (@ "C : \test.txt ", FileMode.Open); } Finally { filestream.dispose (); }}
Use the "using" keyword to further simplify:
private void Buttonopen_click (Object Sender,eventargs e) { using (FileStream FileStream = new FileStream (@ "c \ Test.txt ", FileMode.Open)) { }}
About algebra: Divided into 3 generations: No. 0 generation, 1th generation, 2nd generation.
- No. 0 Generation: This is the youngest generation, which contains short lifetime objects. An example of a short-lived object is a temporary variable. Garbage collection occurs most often in this generation. The newly allocated object forms the next generation of objects and is an implicit No. 0-generation collection, unless they are large objects, in which case they will go into the large object heap in the 2nd generation of collections. Most objects are recycled through garbage collection in generation No. 0 and are not retained to the next generation.
- 1th generation: This generation contains short-lived objects and serves as a buffer between short-lived objects and long-lived objects.
- 2nd generation: This generation contains long-lived objects. An example of a long-lived object is an object in a server application that contains static data that is active during the process.
When conditions are met, garbage collection will occur on a specific generation. Reclaiming a generation means reclaiming the objects in this generation and all of their younger generations. The 2nd generation garbage collection is also known as full garbage collection because it reclaims all objects on all generations (that is, all objects in the managed heap).
Surviving and promoting
objects that are not reclaimed in garbage collection are also known as survivors and are promoted to the next generation. The objects surviving in the No. 0 generation garbage collection will be promoted to the 1th generation, and the objects surviving in the 1th generation of garbage collection will be promoted to the 2nd generation, while the objects surviving in the 2nd garbage collection will remain the 2nd generation.
When the garbage collector detects a high rate of survival in a generation, it increases the allocation threshold for that generation, so the next reclamation will fetch a very large amount of reclaimed memory. The CLR balances before the following two priority levels: not allowing the application's working set to get too much memory and not allowing garbage collection to take too much time.
Temporal and temporary segments
Because objects in the No. 0 and 1th generations have shorter lifetimes, these generations are called the temporal era. The
Temporary generation must be allocated in a memory segment called a temporary segment. Each new segment fetched by the garbage collector becomes the new ephemeral segment and contains the objects that survived the No. 0 generation garbage collection. The old temporary segment will become the new 2nd-generation segment.
C # Recommendations for cost-effective code 52nd-release resources in a timely manner