Introduction:
This article assumes that you are familiar with the "DISPOSE / FINALIZE" mode mentioned in the two articles (GC101, GC102).
Microsoft introduced the pattern of finalization, and the purpose is to make the encoding safer. If a developer refers to an object (Component), forget to destroy it (by calling the Dispose method), this component can still be automatically recycled by GC.
Let me explain some negative effects that implement the descent function (the translation: the factors that have a negative impact on performance): (The following is not existed for those who do not implement the destructor):
1. Objects are placed in "Finalization Queue)
2. Objects move from the "Destructor"
3. Objects are placed in "will be queued" (TO BE Finalized Queue)
4. Destructure method of components should be called
5. Objects move from "The queue to be destructed"
6. You can't accurately know how GC wants to call destructive methods (for resource recovery)
These points outline the impact on the use of the sect. As you can see, the destructure method has a huge impact on performance. The following let us continue to explore this problem:
A conventional thread
The greatest impact in the above points is 4th. The .NET garbage collection mechanism has a working thread specially invoked from the "To BE Finalized Queue". This thread runs at a high priority, so if there are many components that need to release resources (destructors), this working thread will block them in low priority. If there are many garbage to be recycled, your process will be denial of service attack (DOS)!
Into the team / out of the team
The above mentioned the team / out of the team will impact performance. For simple objects, this is acceptable. However, if you want to accurately control its impact on performance, then handle it.
You can't control when GC will perform Finalize (). You only know when it should clean up the garbage: When the resource is no longer needed, and the impact of cleaning the garbage is acceptable. By writing code in the Dispose () or Close () method, you can manually clean up resources in the most correct time.
Don't quote any object
You can't quote any named objects in Finalize (). This is because object recovery is performed in unpredictable order, so you don't know if the referenced object has been recovered before. This will cause you to be restricted when you implement the destructure.
Downgrade Garbage Collection (Overall Degraded Garbage Collection)
GC needs to experience several cycles to recover the designer. This impact is much larger than it seems to be much better, not only makes your objects longer, but also for those objects that it references.
When GC places objects in "To BE Finalized Queue", it will upgrade GC to level 1. The objects in Level 1 are less opportunities to be cleaned than the 0th generation of objects, so that your object is cited for hosted / unmanaged resources that will reside in memory.
Why do you need to implement a destructive function?
Is there any motivation inside? Of course, this is "ensuring" cleaning up the resources occupied by your object. This is the only reason that needs to achieve destructors. If your components use resources, they will be released after use. If the developer explicitly calls the object's Dispose () method (assuming gc.suppressFinalize in Dispose), then this resource will be cleaned up, and you don't have to worry! If a developer forgets to call the DISPOSE method of the object, the GC thread automatically cleans the resource when the destructor is called. But the time to perform the descent is random, which is not allowed to control. in conclusion:
I saw two roads:
1. Put all the proxy of all cleaning resources in the Dispose (or Close) method, the developer is responsible for the work of all object cleaning. If your object uses non-managed resources, this is reasonable because if you forget to clean them, you will cause memory leakage. This will make the developer to complete the cleanup work at any time as needed.
2. Implement the destructor and only clean up the non-hosting resources. Clean all managed resources in the Dispose method.
The most widely accepted is the second, but I am somewhat different, let me explain why:
If the developer calls the object's Dispose method fails, it will cause memory leakage when the measurement (if not yet, then the test work needs to be re-corrected!) After discovering a leak, you can call the object Dispose method here. Then produce best performance.
In a Framework class, there are many ways to realize destructive methods. I will publish it later, please pay attention to my blog.