By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,843 Members | 864 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,843 IT Pros & Developers. It's quick & easy.

GC.Collect

P: n/a
Hi ,

Any pointers when it's absolute necessary to use it .

Does it has a blocking effect on the code , as GC per se is
undeterministic .

what if GC.collect is followed in next line by
GC.WaitForPendingFinalizers , will it actually block .

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 .

TIA ,

Mrinal
Nov 17 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Mrinal,

What is your test suite developer's reason for calling GC.Collect?

If you called GC.Collect on 200 worker threads, it's going to do you
more harm or goo.

Basically, don't do it, it's not a good idea. The GC.Collect method is
there because it has to be (because there are VERY rare cases where it needs
to be used), but in general, you should never be calling it.

Having 200 worker threads, it would seem that calling GC.Collect would
be more of a hinderance.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Mrinal Kamboj" <mr***********@oracle.com> wrote in message
news:%A**************@news.oracle.com...
Hi ,

Any pointers when it's absolute necessary to use it .

Does it has a blocking effect on the code , as GC per se is
undeterministic .

what if GC.collect is followed in next line by GC.WaitForPendingFinalizers
, will it actually block .

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 .

TIA ,

Mrinal

Nov 17 '05 #2

P: n/a
Mrinal,

Yes, GC.WaitForPendingFinalizers blocks until all finalizers (which are
on the finalization queue) have run to completion. That's straight out
of the documentation.

So the test suite developer wants you to call GC.Collect on every
iteration of every thread? You're not the only one that's not
convinced. Is the developer claiming that performance is enhanced by
doing this? He is a test developer so as crazy as this sounds I have
to assume, at least for now, that he has actually tested his
hypothesis. Is that the case?

I'm also concerned about the number of threads. 200 is a lot of
threads. Thread pooling is almost certainly a more appropriate
solution.

Brian

Mrinal Kamboj wrote:
Hi ,

Any pointers when it's absolute necessary to use it .

Does it has a blocking effect on the code , as GC per se is
undeterministic .

what if GC.collect is followed in next line by
GC.WaitForPendingFinalizers , will it actually block .

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 .

TIA ,

Mrinal


Nov 17 '05 #3

P: n/a
"Mrinal Kamboj" <mr***********@oracle.com> wrote in message
news:%A**************@news.oracle.com...
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

Nov 17 '05 #4

P: n/a
Hi All ,

Thanks for the suggestions / pointers , they will definitely help me in
making a wise decision .

just to divulge some more details , i am the developer of the stress
test suite , which is stressing another app. and checking it's
performance under load , where for around 3 hrs. , all 200 threads keep
on going in loop , with a sleep time of 1sec. after every iteration ,
but what i make sure is :

1. No major allocations are done in that loop , essntially not a very
heavy work per iteration .

2. Before leaving the loop , relevant objects are closed , disposed and
nullified , so that's why i never thought it to be necessary to go in
collect method .

but on other end App. developer doesn't want to take a blame of some
arrant mem. leak / handle leak , so he's bent upon using collect and
waitforpendingfinalizers in all iterations , however i don't think by
doing this i am simulating a real scenario .

any more suggestions , most welcome .

thanks ,

Mrinal

Michael S wrote:
"Mrinal Kamboj" <mr***********@oracle.com> wrote in message
news:%A**************@news.oracle.com...
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

Nov 17 '05 #5

P: n/a

"Mrinal Kamboj" <mr***********@oracle.com> wrote in message
news:xt************@news.oracle.com...
Hi All ,
but on other end App. developer doesn't want to take a blame of some
arrant mem. leak / handle leak , so he's bent upon using collect and
waitforpendingfinalizers in all iterations , however i don't think by
doing this i am simulating a real scenario .

Mrinal,

Sounds to me that you are absolutely right. A key goal of a stress test is
to expose memory and resource leaks. By calling Collect/WaitForFinalizers
you are hiding problems due to your developer not correctly calling Dispose
when required. While the finalizer will eventually clean up the resource, in
a realistic scenario that won't happen till the GC gets around to it - in
it's own time. By pre-empting that decision you are hiding potential
problems. (I am assuming here that this is all happening in the same
AppDomain - i.e. what you are testing is some sort of library.)

Of course your developer may have other reasons - so be tactful in tellling
him he's wrong :-)

--------
Nigel Norris
Nov 17 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.