Mrinal Kamboj said:
Hi ,
Any pointers when it's absolute necessary to use it .
I'll try give you a few.. But first a few rules
Rule 1) Never assume you know how many generations .NET uses or their sizes.
(Sure we have 3 of them and gen0 is 256K, but this may change in future
systems and differ on platforms)
Rule 2) The GC knows best when to collect. (It keeps stats for gen2 and
collect at will, while gen1 and gen0 gets collected when full. This may
change in future systems.)
However. There are cases when you may want to collect. These could be:
1) When you are in a huge complex (i.e nested) loops and know you are
allocating plenty of reference-types that is fire and forget (read strings).
Hence they won't survive the outer loop but exist in the inner. I'm talking
about if you got O(N^3) and know that the code will allocate several
thousands or millions of objects. Well for each 65'000 of those objects the
gen0 in .NET 1.1 will get full, the GC kicks in and move most of them to
gen1. And when gen1 gets full the'll be moved to gen2. This is not what you
want for your short lived objects and you can help the GC to collect. By
collecting often you leave more space for other objects.
2) When using COM. If you automate Excel or Word, the marshalling generates
a lot of objects that tends to stick and move to gen1 and gen2 really fast.
If you write a lot of data to excel it is just fair to do a collect when
you're done with the filling.
3) When .NET is eating memory like a hog and you don't know why. A
GC.Collect() is a great debugging-tool for finding poor performance. Just
move that line around in the code until .NET stops eating memory like
Godzilla chews up Tokyo and you just found a place to refactor. =)
Does it has a blocking effect on the code , as GC per se is
undeterministic .
Yes. When the GC kicks in it will block just about everything,one
application domain at a time. But the GC lives in his own thread and you
will hardly notice a gen0 collect. But if gen2 have grown to giga-size and
start collect and re-arrange you will feel a stagger and winamp may lag. =)
This is why you might wanna help the GC sometimes.
what if GC.collect is followed in next line by GC.WaitForPendingFinalizers
, will it actually block .
Yes. or else it would imply that the GC was buggy.
Why i need all this info as in my stress test suite developer is stressing
upon the need to use these things in every iteration of every thread ,
where simultaneously around 200 worker thread are working , so i am not
very convinced about such a high frequency usage .
Well, 200 threads is quite a lot for one application. And as you are
stressing another app, you are stressing your dear .NET runtime with
context-switching. Hence this would be an excellent case for when you want
to help the GC to collect.
But then again, for most applications there is no need to collect. Rule 1
and 2 applies.
Happy Collecting
- Michael S