HighTechTalks DotNet Forums  

GC.Collect and Generations

Dotnet Framework (CLR) microsoft.public.dotnet.framework.clr


Discuss GC.Collect and Generations in the Dotnet Framework (CLR) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Günter Prossliner
 
Posts: n/a

Default GC.Collect and Generations - 08-02-2006 , 03:51 AM






Hi everybody!

As we all know, die Garbage Collector minimizes the time needed for a
collection by using generations. When an object remains uncollected, it
moves one generation up. Higher generations are not collected such often as
lower generations. When an object lives in the generation 2 (the highest in
the current implementation), garbage collection will - under most
circumstances - not happen (this is not documented, but it was pointed out
in some MSDN articles).

Ok.

What if the Developer calls GC.Collect()? I have seen code (not mine), where
GC.Collection was called even within loops! From my understanding this would
result in having object in high generations allthough they are not long
living (maybe just Objects that have a liftime within a simple method). This
would result in a very high memory foodprint, since this objects will not
(or very seldom) get collected.

Or does the GC handle calls to GC.Collect() special? I meen that objects are
not moved into a higher Generation?


c# sample:

void foo(){
SmallMethod();
GC.Collect(); // o will move in gen #1
GC.Collect(); // o will move in gen #2
}

void SmallMethod(){
VeryBigManagedObject o = new VeryBigManagedObject();
}


br GP



Reply With Quote
  #2  
Old   
AJ
 
Posts: n/a

Default Re: GC.Collect and Generations - 08-02-2006 , 08:01 AM







My understanding is...

GC.Collect() isn't special. It attempts to collect, and any remaining
objects will be upped into the next generation.

There aren't many cases when calling GC.Collect() is a good idea. Doing
so inside a loop sounds odd.

By the way, in your example code, the 'o' object will be collected on
the first call since it's no longer rooted... So it doesn't move up the
genreations..


In article <uSKQshgtGHA.1288 (AT) TK2MSFTNGP02 (DOT) phx.gbl>, "Günter Prossliner"
<g.prossliner/gmx/at> says...
Quote:
Hi everybody!

As we all know, die Garbage Collector minimizes the time needed for a
collection by using generations. When an object remains uncollected, it
moves one generation up. Higher generations are not collected such often as
lower generations. When an object lives in the generation 2 (the highest in
the current implementation), garbage collection will - under most
circumstances - not happen (this is not documented, but it was pointed out
in some MSDN articles).

Ok.

What if the Developer calls GC.Collect()? I have seen code (not mine), where
GC.Collection was called even within loops! From my understanding this would
result in having object in high generations allthough they are not long
living (maybe just Objects that have a liftime within a simple method). This
would result in a very high memory foodprint, since this objects will not
(or very seldom) get collected.

Or does the GC handle calls to GC.Collect() special? I meen that objects are
not moved into a higher Generation?


c# sample:

void foo(){
SmallMethod();
GC.Collect(); // o will move in gen #1
GC.Collect(); // o will move in gen #2
}

void SmallMethod(){
VeryBigManagedObject o = new VeryBigManagedObject();
}


br GP




Reply With Quote
  #3  
Old   
Jay B. Harlow [MVP - Outlook]
 
Posts: n/a

Default Re: GC.Collect and Generations - 08-02-2006 , 08:26 AM



Günter,
Quote:
What if the Developer calls GC.Collect()? I have seen code (not mine),
where
GC.Collection was called even within loops!
Short answer is *don't* call GC.Collect in a loop.

For details on when you should & when you shouldn't (call GC.Collect) see
the four web pages on the GC at:

http://www.tsbradley.net/Reading/CLR.aspx

Especially read these two:

http://blogs.msdn.com/ricom/archive/...29/271829.aspx
http://blogs.msdn.com/ricom/archive/.../02/40780.aspx

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


"Günter Prossliner" <g.prossliner/gmx/at> wrote

Quote:
Hi everybody!

As we all know, die Garbage Collector minimizes the time needed for a
collection by using generations. When an object remains uncollected, it
moves one generation up. Higher generations are not collected such often
as
lower generations. When an object lives in the generation 2 (the highest
in
the current implementation), garbage collection will - under most
circumstances - not happen (this is not documented, but it was pointed out
in some MSDN articles).

Ok.

What if the Developer calls GC.Collect()? I have seen code (not mine),
where
GC.Collection was called even within loops! From my understanding this
would
result in having object in high generations allthough they are not long
living (maybe just Objects that have a liftime within a simple method).
This
would result in a very high memory foodprint, since this objects will not
(or very seldom) get collected.

Or does the GC handle calls to GC.Collect() special? I meen that objects
are
not moved into a higher Generation?


c# sample:

void foo(){
SmallMethod();
GC.Collect(); // o will move in gen #1
GC.Collect(); // o will move in gen #2
}

void SmallMethod(){
VeryBigManagedObject o = new VeryBigManagedObject();
}


br GP





Reply With Quote
  #4  
Old   
Jay B. Harlow [MVP - Outlook]
 
Posts: n/a

Default Re: GC.Collect and Generations - 08-02-2006 , 09:31 AM



I should add to my other comments. Another method I've used instead of
calling GC.Collect directly is a HandleCollector:

http://msdn2.microsoft.com/en-us/lib...llector.asp x

Generally in the use of Win32 handles or COM objects.

I encapsulate the COM object in a .NET class (a proxy pattern) in the
constructor of the proxy I call HandleCollector.Add in the proxy's Dispose
method I call HandleCollector.Remove & ReleaseComObject.

This way if Disposed is not getting called, the HandleCollector will cause a
GC.Collect & clean up any extras...


--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


"Günter Prossliner" <g.prossliner/gmx/at> wrote

Quote:
Hi everybody!

As we all know, die Garbage Collector minimizes the time needed for a
collection by using generations. When an object remains uncollected, it
moves one generation up. Higher generations are not collected such often
as
lower generations. When an object lives in the generation 2 (the highest
in
the current implementation), garbage collection will - under most
circumstances - not happen (this is not documented, but it was pointed out
in some MSDN articles).

Ok.

What if the Developer calls GC.Collect()? I have seen code (not mine),
where
GC.Collection was called even within loops! From my understanding this
would
result in having object in high generations allthough they are not long
living (maybe just Objects that have a liftime within a simple method).
This
would result in a very high memory foodprint, since this objects will not
(or very seldom) get collected.

Or does the GC handle calls to GC.Collect() special? I meen that objects
are
not moved into a higher Generation?


c# sample:

void foo(){
SmallMethod();
GC.Collect(); // o will move in gen #1
GC.Collect(); // o will move in gen #2
}

void SmallMethod(){
VeryBigManagedObject o = new VeryBigManagedObject();
}


br GP





Reply With Quote
  #5  
Old   
Günter Prossliner
 
Posts: n/a

Default Re: GC.Collect and Generations - 08-02-2006 , 10:04 AM



Hello!

Quote:
There aren't many cases when calling GC.Collect() is a good idea.
Doing so inside a loop sounds odd.
I have not done this and will never do this.

But on reviewing Code of my employees, I see this too often. If the objects
move up in Generations, GC.Collect() would not only result in lesser
performance, but also in a bigger memory footprint! This would be a very
very good argument to prove that GC.Collect() is "bad".

Quote:
By the way, in your example code, the 'o' object will be collected on
the first call since it's no longer rooted... So it doesn't move up
the genreations..
Ok. The example is wrong. This shall be correct:

VeryBigManagedObject o;

void foo(){
SmallMethod();
GC.Collect(); // o will move in gen #1
GC.Collect(); // o will move in gen #2
SmallMethod2();
}

void SmallMethod(){
o = new VeryBigManagedObject();
}

void SmallMethod2(){
o = null;
}

Is this statement true:
"Without GC.Collect() the CLR would release the managed memory from 'o' much
earlier, because it will be in gen #0."



br GP




Reply With Quote
  #6  
Old   
Günter Prossliner
 
Posts: n/a

Default Re: GC.Collect and Generations - 08-02-2006 , 10:23 AM



Hallo Jay!

Quote:
Short answer is *don't* call GC.Collect in a loop.
I know (see my answer to AJ)

Quote:
For details on when you should & when you shouldn't (call GC.Collect)
see the four web pages on the GC at:

http://www.tsbradley.net/Reading/CLR.aspx
Some of them I already know.

These articles I have not read before. Interesting!


Thank you!
GP




Reply With Quote
  #7  
Old   
Greg Young
 
Posts: n/a

Default Re: GC.Collect and Generations - 08-03-2006 , 01:43 PM



Just to add to the others ... "VeryBigManagedObject " is likely to end up in
the LOH if it is actually a very big managed object anyways. If so the
collects would not actually move it.

Cheers,

Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung


"Günter Prossliner" <g.prossliner/gmx/at> wrote

Quote:
Hi everybody!

As we all know, die Garbage Collector minimizes the time needed for a
collection by using generations. When an object remains uncollected, it
moves one generation up. Higher generations are not collected such often
as lower generations. When an object lives in the generation 2 (the
highest in the current implementation), garbage collection will - under
most circumstances - not happen (this is not documented, but it was
pointed out in some MSDN articles).

Ok.

What if the Developer calls GC.Collect()? I have seen code (not mine),
where GC.Collection was called even within loops! From my understanding
this would result in having object in high generations allthough they are
not long living (maybe just Objects that have a liftime within a simple
method). This would result in a very high memory foodprint, since this
objects will not (or very seldom) get collected.

Or does the GC handle calls to GC.Collect() special? I meen that objects
are not moved into a higher Generation?


c# sample:

void foo(){
SmallMethod();
GC.Collect(); // o will move in gen #1
GC.Collect(); // o will move in gen #2
}

void SmallMethod(){
VeryBigManagedObject o = new VeryBigManagedObject();
}


br GP




Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.