This post originated from an RSS feed registered with .NET Buzz
by Steve Hebert.
Original Post: (Amazing) Code Smell - GC.Collect()
Feed Title: Steve Hebert's Development Blog
Feed URL: /error.htm?aspxerrorpath=/blogs/steve.hebert/rss.aspx
Feed Description: .Steve's .Blog - Including .Net, SQL Server, .Math and everything in between
I was reading Jeremy Miller's post on Code Smells
and another classic .Net code smell occurred to me. (I have to
say I love the term 'Code Smell' - I use it all the time now. Thanks
Jeremy.)
The most insidious .Net coding smell I've run across is:
GC.Collect()
If you search your application and find this call, stop everything you
are doing and focus on this problem. Go check for this problem,
I've seen it happen in runtime environments at 4 different companies so
far. I recently talked to one
programmer who bashed the .Net garbage collection performance because
he said the model was to simply consume memory until it runs out of
it. Guess what - once again "GC.Collect()" was being called.
From what I've seen, GC.Collect typically gets injected into
applications when memory resources aren't released. Rather than
understanding the root problem, GC.Collect gets thrown into the mix.
The patch of running GC.Collect() in your application will allow
your application to run longer, but the memory allocation changes to a
progressive stairstep effect where the process eventually hangs.
The Garbage Collector is doing it's job correctly, however it's the
routine and predictable calling of the collector that forces normally
transient objects to be promoted to a status of "less transient" (my
term, not theirs). If you are calling this within your
application you are introducing the same memory allocation path to the
compiler each time and the same objects get promoted. This
promotion process is the normal functioning of garbage collection that
allows the garbage collector to perform more efficiently and prevents
the system from hanging for minutes on end like the old BASICA garbage
collector. Given this behavior and the articles I've read on the subject,
I believe garbage collection in a framework environment like .Net and
Java is predicated on running at random intervals to the application -
allowing for a random distribution of errantly identified
'non-transient" objects. This also helps explain the need for multiple
levels of promotion.
If you run into memory allocation problems within your application,
resist the decision to inject GC.Collect() at all cost. Go out
and buy a tool like Red-Gates ANTS Profiler for .NET
and take the time to understand the root problem. If you go the
GC.Collect route, you will typically delay the problem until production
at which time profiling will include side-effects of the GC.Compiler
call and will delay the understanding of the core issues even longer
when the cost is greatest.