When should I use GC.SuppressFinalize ()?

6
  • In .NET, under what circumstances should GC.SuppressFinalize() be used?
  • What are the advantages of using this method?

Note: I found the answer in the SO-en: When should I use GC.SuppressFinalize ()? As I did not have something related in pt-br I decided to reproduce the question here so that we have a source in Portuguese.

    
asked by anonymous 08.12.2015 / 14:35

2 answers

5

Some questions that may help you understand the theme:

There are some classes that have "features" that go beyond the contents of managed memory. In these cases the class itself must take some action on how to proceed with the destruction of its content. It needs a finalizing method. This is very common in the implementation of the layout pattern ( IDisposable interface). The finalizer is useful in all situations where the destruction of the object must be personalized and goes beyond the deallocation of memory, which only the GC can carry out, in the way it desires.

This is a way of telling the GC that he should not call the finalizer since he was called by the class at an earlier time. If it is called, it will try to perform a cleanup that has already been performed and there will probably be a problem.

Implementation example:

public class MyClass : IDisposable {
    private bool disposed = false;
    protected virtual void Dispose(bool disposing) {
        if (!disposed) {
            if (disposing) {
                // chamado pelo myClass.Dispose(). 
                // OK usar quaisquer referências para objetos privados
            }
            disposed = true;
        }
    }

    public void Dispose() { // necessário para a interface IDisposable
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~MyClass() { //método finalizador (destrutor)
        Dispose(false);
    }
}

The provision should only be used in specific cases where it really is needed. One can not be tempted to force resource release when only managed memory is allocated. This does not work. The release of memory can only be performed by the GC. The method GC.SuppressFinalize() only reports that the finalization has already been performed, not that the memory release occurred. I could not even do this. The memory allocation of the CLR is done in its own way and in an integrated way, the application has no control over it. You can not control a portion of the allocation. It's one thing.

For those who are not sure what to do in these cases, it is best to follow the above recipe. But it would be good to study the subject a lot before creating a class that relies on external resources. Most applications do not need this. Just consume what already exists.

There is no performance problem in using it. Unless the particular algorithm used in the finalizer has a performance problem of its own, it is not the fault of this GC method.

Another OS question on the subject .

    
08.12.2015 / 15:05
2

It should be used when the class is finished.

When you use the recommendation, you use an implementation of IDisposable:

This is an implementation I did in a project:

public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
public void Dispose(bool v)
{
    if (v)
    {
        if (db != null) { db.Dispose(); db = null; }
    }
}

Updating The current answer was wrong, I'm updating the bigown hint in the comment.

Objects that implement the IDisposable interface can call this method of execution to prevent the garbage collector from calling Object.Finalize on an object that does not require this. Typically, this is done to prevent the finalizer from releasing unmanaged resources that have already been freed by the IDisposable.Dispose implementation.

    
08.12.2015 / 14:44