When should I use GC.Suppressfinalize()?

Asked

Viewed 1,919 times

9

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

Obs: I found answer in the SO-en: When should I use GC.Suppressfinalize()? As it had nothing to do with pt-br I decided to reproduce the question here so that we have a Portuguese source.

  • I imagine you essentially want that excellent answer. Do you know English? Do you know that you can post the answer yourself? Do you want to do this? Or would you rather have someone post here?

  • I do not intend to answer at first, only if someone does not answer for a long time (1 week).

2 answers

7


Some questions that may help you understand the theme:

There are some classes that have "features" that go beyond the content of the managed memory. In these cases the class itself must take some action of how to proceed the destruction of its content. It needs a finalizer method. This is very common in implementing the layout pattern (interface IDisposable). The finisher is useful in all situations that the destruction of the object must be customized and goes beyond the displacement of the memory, that only the GC can proceed, however you want.

This is a way to indicate to the GC that it should not call the finalizer, since it was called by the class at an earlier time. If it is called, it will attempt to perform a cleanup that has already been performed and probably some problem will occur.

Example of implementation:

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);
    }
}

I put in the Github for future reference.

The provision should only be used in specific cases where it is really necessary. One cannot be tempted to force the release of resources when only managed memory is allocated. This does not work. The memory release can only be performed by the GC. The method GC.SuppressFinalize() only informs that the completion has already been accomplished, not that the memory release has occurred. Nor could it do this. The memory allocation of the CLR is done in an entirely own way and in an integrated way, the application has no control over it. You can’t control a part of the allocation. It’s one thing.

For those who do not know well what to do in these cases, it is better to follow the recipe above. But it would be good to study the subject thoroughly before creating a class that relies on external resources. Most applications don’t need this. Just consume what already exists.

There is no problem of performance in using it. Unless the specific algorithm used in the finalizer has some performance problem of its own, but it will not be the fault of this GC method.

Other OS question on the subject.

3

It should be used when the class is finished.

When using the recommendation is to use an implementation of IDisposable:

This is an implementation I did on 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 am updating conforms Maniero’s tip in the comment.

The objects that implement the interface IDisposable can call this method of execution, to prevent the garbage collector from calling Object.Finalize() in an object that does not require it. This is usually done to prevent the finalizer from releasing unmanaged resources that have already been released by the implementation IDisposable.Dispose().

Browser other questions tagged

You are not signed in. Login or sign up in order to post.