When is it acceptable to call GC.Collect?

0 votes
asked Jan 25, 2009 by brian-rasmussen

The general advise is that you should not call GC.Collect from your code, but what are the exceptions to this rule?

I can only think of a few very specific cases where it may make sense to force a garbage collection.

One example that springs to mind is a service, that wakes up at intervals, performs some task, and then sleeps for a long time. In this case, it may be a good idea to force a collect to prevent the soon-to-be-idle process from holding on to more memory than needed.

Are there any other cases where it is acceptable to call GC.Collect?

21 Answers

0 votes
answered Jan 24, 2009 by ian-ringrose

The best practise is to not force a garbage collection in most cases. (Every system I have worked on that had forced garbage collections, had underlining problems that if solved would have removed the need to forced the garbage collection, and speeded the system up greatly.)

There are a few cases when you know more about memory usage then the garbage collector does. This is unlikely to be true in a multi user application, or a service that is responding to more then one request at a time.

However in some batch type processing you do know more then the GC. E.g. consider an application that.

  • Is given a list of file names on the command line
  • Processes a single file then write the result out to a results file.
  • While processing the file, creates a lot of interlinked objects that can not be collected until the processing of the file have complete (e.g. a parse tree)
  • Does not keep match state between the files it has processed.

You may be able to make a case (after careful) testing that you should force a full garbage collection after you have process each file.

Another cases is a service that wakes up every few minutes to process some items, and does not keep any state while it’s asleep. Then forcing a full collection just before going to sleep may be worthwhile.

The only time I would consider forcing a collection is when I know that a lot of object had been created recently and very few objects are currently referenced.

I would rather have a garbage collection API when I could give it hints about this type of thing without having to force a GC my self.

See also "Rico Mariani's Performance Tidbits"

0 votes
answered Jan 25, 2009 by casperone

In your example, I think that calling GC.Collect isn't the issue, but rather there is a design issue.

If you are going to wake up at intervals, (set times) then your program should be crafted for a single execution (perform the task once) and then terminate. Then, you set the program up as a scheduled task to run at the scheduled intervals.

This way, you don't have to concern yourself with calling GC.Collect, (which you should rarely if ever, have to do).

That being said, Rico Mariani has a great blog post on this subject, which can be found here:


0 votes
answered Jan 25, 2009 by brian

One case is when you are trying to unit test code that uses WeakReference.

0 votes
answered Jan 25, 2009 by m4n

Have a look at this article by Rico Mariani. He gives two rules when to call GC.Collect (rule 1 is: "Don't"):

When to call GC.Collect()

0 votes
answered Jan 25, 2009 by jon-skeet

If you have good reason to believe that a significant set of objects - particularly those you suspect to be in generations 1 and 2 - are now eligible for garbage collection, and that now would be an appropriate time to collect in terms of the small performance hit.

A good example of this is if you've just closed a large form. You know that all the UI controls can now be garbage collected, and a very short pause as the form is closed probably won't be noticeable to the user.

0 votes
answered Jan 25, 2009 by ctacke

Scott Holden's blog entry on when to (and when not to) call GC.Collect is specific to the .NET Compact Framework, but the rules generally apply to all managed development.

0 votes
answered Jan 25, 2009 by bankz

The short answer is: never!

0 votes
answered Jan 25, 2009 by marc-gravell

I use GC.Collect only when writing crude performance/profiler test rigs; i.e. I have two (or more) blocks of code to test - something like:

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
TestA(); // may allocate lots of transient objects
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
TestB(); // may allocate lots of transient objects
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

So that TestA() and TestB() run with as similar state as possible - i.e. TestB() doesn't get hammered just because TestA left it very close to the tipping point.

A classic example would be a simple console exe (a Main method sort-enough to be posted here for example), that shows the difference between looped string concatenation and StringBuilder.

If I need something precise, then this would be two completely independent tests - but often this is enough if we just want to minimize (or normalize) the GC during the tests to get a rough feel for the behaviour.

During production code? I have yet to use it ;-p

0 votes
answered Jan 25, 2009 by chris-s

This isn't that relevant to the question, but for XSLT transforms in .NET (XSLCompiledTranform) then you might have no choice. Another candidate is the MSHTML control.

0 votes
answered Jan 25, 2009 by joel-coehoorn

You can call GC.Collect() when you know something about the nature of the app that the garbage collector doesn't. It's tempting to think that, as the author, this is very likely. However, the truth is that the GC amounts to a pretty well-written and tested expert system, and it's rare that you'll know something about the low level code paths that it doesn't.

The best example I can think of where you might have some extra information is a app that cycles between idle periods and very busy periods. You want the best performance possible for the very busy periods and therefore want to use the idle time to do some clean up.

However, most of the time the GC is smart enough to do this anyway.

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter