If the object was deleted, does gc finalizer suppress some time?

Garbage collection can be a time consuming process. In this regard, the GC tends to work only when necessary. If an object has been deleted to help save time and help the GC, should the GC finalizer be suppressed?

using(var sO = new someObject()) { //work with object } public class someObject : IDisposable { internal Stream someResource; internal Context someContext; public void Dispose() { someContext.Dispose(); someResource.Dispose(); //A: does suppressing the GC finalizer here save time for the GC? //B: can this cause memory leaks? //GC.SuppressFinalize(this); } } 
+4
source share
3 answers

To fix some confusion:

  • You only need a finalizer if you need to clean up unmanaged resources in a special way.

  • If you do not have unmanaged resources, you do not need a finalizer.

  • If you have a finalizer, you should definitely implement IDisposable.

  • If you have a finalizer, you should call GC.SuppressFinalize in Dispose, because the finalizer does not need to be called if you have already cleared after yourself.

  • You only need to call GC.SuppressFinalize if you have a finalizer. If you do not, you probably still want to call it a protective measure.

suppresses the GC finalizer here, saves time for the GC?

If there are unmanaged resources, and your object has a finalizer, then yes; your object may be in the finalization queue for a long time if you do not suppress it. The resources you have can also take a long time to complete (for example, closing an expensive I / O channel).

If you don’t have a finalizer, you say that you don’t have anything unmanageable to clean up. You should still call SuppressFinalize a protective measure anyway.

From the rules of FxCop:

"The inability to suppress finalization reduces performance and offers no benefits."


For your other question,

Could this cause a memory leak?

In this example, yes, if any of the resources is unmanageable. If your object ends in some unusual way before it can call Dispose , unmanaged resources will not be properly freed. Consider what happens if someResource unmanaged and throws an exception, for example when using an instance of someObject .

If your object rests on unmanaged resources, and you need to ensure that these resources are cleared, you also need a finalizer (which will be called ~someObject in your case).

+4
source

If you are actively Dispose an object, then yes, you must suppress finalization. There is no need for the object to be modified if you actively / deterministically release all resources. If you let it freeze, the finalizer simply wasted time later.

+3
source

One point that has not yet been mentioned: an object should only be considered β€œlive” if there is some way of execution through which code may be required to access its fields or the object header (data structure that contains information about the type of object, regardless of whether it was used as a monitor lock, etc.). If the object field contains an unmanaged descriptor, and the last thing the Dispose method does is close the descriptor, it is possible that the object may become usable, and the Dispose method is started. Unfortunately. Not only GC.SuppressFinalize call to GC.SuppressFinalize serve to prevent the finalizer from completing after its execution; placing it as the last Dispose element will prevent the object from being finalized before executing it.

+1
source

Source: https://habr.com/ru/post/1402339/


All Articles