views:

147

answers:

6

Hi everyone,

I'm currently writing a paper for my company, about how to avoid calling the garbage collector directly from the code (when playing with COM objects for instance).

I know this is a bad practice, and should be only considered in very rare cases, but I can't seem to find a way to tell why it should be avoided. And I don't want to rely on the "The G.C. is smarter than you" principle (even if it is the truth :-) )

So can you tell me some clues about why you think one should avoid to call the garbage collector directly ? (performance impact?) Or maybe if you have links about this particular topic, they would be very helpful.

Thanks in advance !

Edit: All the aswers you provided until now are really helpful. As I can't validate everyone (or can I ?), what should I do ? Make a community wiki ?

+1  A: 

Check this article will provide you enough information about grabage collector : Garbage Collection in .NET

Pranay Rana
+4  A: 

The main reason is that a program that spends more time than necessary performing full collections in the GC will be slower than it needs to be.

Given that this is a situation where it is easier to get better performance, seems like a no brainer to me!

NB. When playing with COM objects, calling the GC directly is unlikely to solve your problem. If COM objects are hanging around then they have non-zero ref counts, and no amount of extra GC calls will fix that.

Daniel Earwicker
But on the other hand, there are some COM object that do not disappear even after the COM objects have 0 ref counts. I've seen this happening with the Excel COM object.
Vinko Vrsalovic
Vinko, that's exactly the example taken in my document. But it is possible to remove all references without explicitely call the G.C.
Shimrod
Yes, the problem with Excel is usually that you app created references to an object without actually keeping the reference (for example by doing something like `Sheets(0).SomeSheetMethod` which creates an instance of a Sheet which isn't kept and so can't be explicitly deallocated).
ho1
That's exactly what I'm explaining in my document ho1 :-) So there is no need to call the G.C., as soon as you understand this. Do you know if this behavior is common to all COM objects, or only to those created by Excel ?
Shimrod
+1  A: 

It has performance impact since all threads need to be stopped in order for it to perform collection. After that it needs to determine what is used and what is not and so on...

All that takes time and garbage collector will only work when it determines that benefit is greater than harm.

When you call GC yourself you will most probably just call it too often and this will increase time spent in GC and decrease time spent in your program.

Josip Medved
+2  A: 

Hi,

There's a good explanation by MS here. There's a section which basically answers your question (namely: performance) which may be useful.

Cheers, Adam

AJ
+1  A: 

If you need to call the GarbageCollector to make sure the COM objects are released, it's probably a good sign that your developers don't call Dispose and/or don't use using when they should. So one argument could be that it would just be hiding the bad code and it would be better to fix the bad code instead.

ho1
COM objects don't tend to support `IDisposable`, so this isn't going to directly be a solution.
Daniel Earwicker
@Daniel Earwicker: You misunderstand, I meant it as the COM objects being an unmanaged resource that you might need to clean up in some way or other (maybe `ReleaseComObject`) in your `Dispose` methods. And if the developer of that class that uses the COM objects have written it to clean up in the Dispose, then the callers of the class should call `Dispose` or use `using`.
ho1
No, I get that. That's why I said *directly*. :)
Daniel Earwicker
@Daniel: Well then I misunderstood, so I was at least partly correct, one of use had misunderstood.
ho1
+1  A: 

The usual performance argument runs thus:

Generational GC are fast because they rely on the heuristic that many allocated objects are short-lived (an object is "live" as long as it is reachable; the point of the GC is to detect "dead" objects and reclaim their memory). This means that objects can be accumulated in a special area (the "young generation"); the GC runs when that area is full, and scavenges the live objects, moving them ("physically") into the old generation. In most generational GC, this operation implies a pause ("stop-the-world") which is tolerable because it is short (the young generation is of limited size). The fact that the world is paused during a collection of the young generation allows for efficient handling of young objects (namely, reading or writing a reference in a young object fields is a mere memory access without needing to account for concurrent access from a GC thread or incremental mark&sweep).

A young generation, with a collection ran as I describe above, is efficient because when the young generation is collected, most of the objects in it are already dead, so they incur no extra cost. The optimal size of the young generation is a trade-off between the worst case (all young objects are live, which implies the maximum pause time) and the average efficiency (when the young generation is larger, more objects have time to die before the collection, which lowers the average cost of GC).

Running the GC manually is similar to making the young generation shorter. It means that more young objects will be promoted to the old generation, thus increasing the cost of the collection of the young generation (more objects must be scavenged) and the cost of the collection of the old generation (more old objects to handle).

Thomas Pornin