22

I found this piece of code inside System.Web.ISAPIRuntime using Reflector

public void DoGCCollect()
{
    for (int i = 10; i > 0; i--)
    {
        GC.Collect();
    }
}

Can anyone comment on this? Is there a reason to do GC.Collect() in a loop? Why 10 times and not 3, 5 or 20? Analysis indicated that it's not used inside .net framework but it's public so I suppose that IIS could call it...

edit :

Just for clarification purposes : I have never called GC.Collect and I have no intentions of using it. I know it's a bad idea in most (if not all) cases. The question is why .net framework does it. Thanks for all your answers.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Diadistis
  • 12,086
  • 1
  • 33
  • 55

8 Answers8

14

Yes, that's horrible. Firstly, you shouldn't need to do it at all. However, if you really want to force garbage collection as hard as you can, and wait for it to finish, you should probably use:

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// Collect anything that's just been finalized
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

Really not a nice idea though.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I'm not using it at all, in fact I've never used GC.Collect() in my apps, and I can't understand why this code exists in .net framework – Diadistis Mar 17 '09 at 11:09
  • Eek - I hadn't spotted that this is part of the .NET framework itself. That's even more revolting. Ah well. – Jon Skeet Mar 17 '09 at 11:27
  • Incidentally, does this absolutely *guarantee* that all unreachable objects will be disposed of? I had the impression that different implementations of the GC are at liberty to use heuristics to speed up collection at the cost of completeness. – Konrad Rudolph Mar 17 '09 at 11:39
  • @Konrad: Using "Forced" instead of "Optimized" will push the GC as far as it's willing to be pushed, I believe. I don't know whether that's absolutely guaranteed to clean up everything, but it's as close as you can get :) – Jon Skeet Mar 17 '09 at 11:54
  • AFAIK, the large object heap will never be collected by the GC – Brann Mar 17 '09 at 12:46
  • @Brann: Large objects are *collected* but the LOH is never *compacted*. There's a big difference :) – Jon Skeet Mar 17 '09 at 14:30
  • i am using the below statements in while loop...it's not working (i am getting OutOfMemoryException) GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); – Praveen Kumar Feb 09 '12 at 07:52
  • @PraveenKumar: Then maybe you're accumulating objects which can't be collected? – Jon Skeet Feb 09 '12 at 08:25
  • nw i am using GC.Collect() inside the while loop.then how can i solve outofmemoryexception? – Praveen Kumar Feb 09 '12 at 08:36
  • 2
    @PraveenKumar: Calling `GC.Collect` at all is rarely the right way to solve `OutOfMemoryException` - chances are you're just holding on to references you shouldn't be. Use a profiler to find out what. – Jon Skeet Feb 09 '12 at 09:26
8

Looks truly horrible :)

Grzenio
  • 35,875
  • 47
  • 158
  • 240
5

I don't think you're going to get a better explanation that "one of Microsoft's programmers is pretty clueless, and apparently, no one else bothered to look at his code before it was checked in". ;)

It does look scary though.

It's a fairly common response to bugs you don't understand though. For whatever reason, you're trying to call the GC, and somehow, calling it doesn't seem to solve your problem (perhaps the real problem was just that you should wait for the finalizer thread or something), so the naive solution is obviously "Well, I'll just keep calling it then".

Similar to pressing 'print' repeatedly until your document is printed.

Perhaps you should submit it to thedailywtf.com though.

jalf
  • 243,077
  • 51
  • 345
  • 550
2

I really like the Mono implementation of this method:

public void DoGCCollect ()
{
  // Do nothing.
}

Probably the developer intended to write something similar and this is just a typo.

cvlad
  • 608
  • 1
  • 6
  • 17
2

Shouldn't things like this be pointed out to Microsoft? Would it do any good to post this on the Connect site?

Chris Dunaway
  • 10,974
  • 4
  • 36
  • 48
1

Looks like someone with a doomsday complex wrote it with connotations that they'd be ending the world with a 10 second timer...

cjk
  • 45,739
  • 9
  • 81
  • 112
0

This is not a good idea because you really ought to trust the garbage collector to do its job without being invoked specifically from your code.

99.9% of the time you never need to call the GC from your code.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
0

First of all it is not a good idea to call GC.Collect(). Calling it multiple times has little effect.

However, you sometimes see the pattern of calling Collect(), then WaitForPendingFinalizers(), and then finally Collect() again. The idea behind this is to ensure that instances with finalizers are also reclaimed, as they will survive the first collection. Keep in mind tough that this will induce a delay in the application and it should very rarely be needed.

Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317