none
What happens if GC.Collect() and GC.SuppressFinalize(this) are called one after the other? RRS feed

  • Question

  • Could I know what happens if I Call GC.Collect() and GC.SuppressFinalize(this) are called one after the other in IDisposable Interface like below.

           #region IDisposable Members

            public void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }

            protected void Dispose(bool disposing)
            {
                this.Adapter.Dispose();
                this._DischargeSummaryTableAdapter.Dispose();
                GC.Collect();
            }

            #endregion

    a dedicated learner
    Friday, April 24, 2009 3:40 PM

Answers

  • GC.Collect may or may not mark your object as not reacheable. (If it's not reachable, the next time the GC is invoked it reclaims the memory.)
    There's no need to call GC.Collect in your example. Explicit calls to GC.Collect greatly degrade performance, one reason is because GC is a self tweaking engine that keeps statistics to find out how frequently should it run - and your manual calls ruin all stats.

    Next, CG.SuppressFinalize(this) simply tells that GC should not call the finalizer for the your object (finalizer should cleanup unmanaged resources - file handles, window handles, etc). If youc class does not implement Finalizer, it won't be marked for finalization and thus no need to call SuppressFinalize. But technically, in your case a reference to this would still exist so nothing bad would happen.

    But nothing good as well.

    So, short answer is don't call GC.Collect and dont suppress finalization if you don't implement Finalizer.
    Long answer is read about Dispose Pattern :)




    Friday, April 24, 2009 4:11 PM

All replies

  • Hello.
    You should check the counters for instance.
    The safest thing is not happening because when you run GC.Collect (), your object is still referenced and execution GC.SuppressFinalize (this), you do for the next execution of the GC

    Pablo
    Friday, April 24, 2009 3:49 PM
  • Nothing much at all.  Dispose() does not release memory, it releases non-memory resources.  Well, it will have an affect, it will make your program run very inefficiently with lots of objects in generation 2 that don't belong there.

    Hans Passant.
    Friday, April 24, 2009 3:49 PM
    Moderator
  • Nothing much at all.  Dispose() does not release memory, it releases non-memory resources.  Well, it will have an affect, it will make your program run very inefficiently with lots of objects in generation 2 that don't belong there.

    Hans Passant.
    Pardon, I don't understand what you actually want to say. Could you please tell me with an example?
    a dedicated learner
    Friday, April 24, 2009 4:05 PM
  • GC.Collect may or may not mark your object as not reacheable. (If it's not reachable, the next time the GC is invoked it reclaims the memory.)
    There's no need to call GC.Collect in your example. Explicit calls to GC.Collect greatly degrade performance, one reason is because GC is a self tweaking engine that keeps statistics to find out how frequently should it run - and your manual calls ruin all stats.

    Next, CG.SuppressFinalize(this) simply tells that GC should not call the finalizer for the your object (finalizer should cleanup unmanaged resources - file handles, window handles, etc). If youc class does not implement Finalizer, it won't be marked for finalization and thus no need to call SuppressFinalize. But technically, in your case a reference to this would still exist so nothing bad would happen.

    But nothing good as well.

    So, short answer is don't call GC.Collect and dont suppress finalization if you don't implement Finalizer.
    Long answer is read about Dispose Pattern :)




    Friday, April 24, 2009 4:11 PM
  • "Pardon, I don't understand what you actually want to say. Could you please tell me with an example?"

    I don't know about an example, but I'll try to explain using your code....


    When you do this:


    public void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }

            protected void Dispose(bool disposing)
            {
                this.Adapter.Dispose();
                this._DischargeSummaryTableAdapter.Dispose();
                GC.Collect();
            }


    There are a few things happening.  The main one is that you're calling disposing on Adapter + _DischargeSummaryTableAdapter, which is the important thing.  This doesn't free memory - what it does is releases any non-managed resources held by these objects, since the garbage collector doesn't "know" about them.

    However, calling GC.Collect() is probably not something you want to do.

    GC.Collect will go through and do a full generation 2 garbage collection at this point, which can be a slow process.  The GC.Collection process will not, at this point, though, collect this object, nor will it collect Adapter or _DischargeSummary, since all three object still have a reference pointed at them from a living object (the object that just called Dispose(), for example, is guaranteed to have a reference to "this" object).  The only objects in this hierarchy that may be cleaned up from this are objects that Adapter or _DischargeSummaryTableAdapter used to point at, but has set to null now as part of their Dispose() function.  However, GC.Collect will go through all three generations and collect every object in the three that are not needed at this point, which can take a while.

    This object, as well as Adapter and _DischargeSummaryTableAdapter, will get cleaned up in a future garbage collection cycle.

    I would highly recommend removing the GC.Collect() call from this.  Trust the GC - it does a very good job of deciding when it needs to clean up memory.  The garbage collection happens automatically in .NET - you never have to explicitly ask the GC to collect memory, since it will do it when it needs to do it.

    Reed Copsey, Jr. - http://reedcopsey.com
    Friday, April 24, 2009 4:51 PM
    Moderator