analyze time spent in garbage collector
springy
Posts: 15
Can Performance Profiler help me in finding out where in my code Gargabe Collection occurs the most time?
There exist 3 performance counters "# Gen X Collections" but they are just increasing steadily -- associating their delta changes with source code would be an interresting thing, wouldn't it? (At least as long GC's are not concurrent.)
There exist 3 performance counters "# Gen X Collections" but they are just increasing steadily -- associating their delta changes with source code would be an interresting thing, wouldn't it? (At least as long GC's are not concurrent.)
Comments
What you can control, possibly, is the rate of allocations of objects. The GC algorithm works independently of the code being run.
I'm speaking of routines/methods which get called some million times and where it's very likely that short living (=Gen0 and Gen1) memory is allocated and freeded at recurring places -- which I want to isolate.
What I've read about your alpha/beta programm "Memory Tracker" seems to be which I'm looking for. Unfortunately it doesn't work -- either it's not compatible with .NET 4 / 64bit or something different.
ANTS Memory Profiler does not help, too, since there are no memory leaks -- but there is heavy GC usage which I want to reduce.
The problem is that there are many hidden places where objects could be created, for example when using LINQ with lambdas which create closures. This is happening behind the scenes, there is no "new SomeObject()" constructor call you easily could spot.
Guess you could use Windows performance monitor and set up an alert when the app's % time spent in GC gets to a certain level and have this trigger a dumpheap and a stack dump with CDB. I've never done this but it sounds possible.
Since Memory Profiler already forces non-concurrent garbage collections maybe changes are higher in finding or at least narrowing down problem areas with this tool?
This gets translated to ILASM code whose C# translation looks like this:
So although I'm using only a well known object (of type TransactionHistory) there have been created 2 additional anonymous (and temporary) classes for each instance of TransactionHistory I`m retrieving from the DB.
While the temporary object most likely won't get promoted to Gen1 this still puts a load on GC collections which would be avoidable at all by refactoring the code into something smarter.
Have you tried including all the memory counters including the Gen 0/Gen 1 promoted (bytes/sec) counters - these are most useful as they give rates of activity rather than absolute values? You should then be able to correlate GC activity with your code (although, as Brian points out- it is an indirect correlation).
Even though it's a performance problem maybe it's easier to tackle this problem using Memory profiler since Memory profiler already disabled concurrent garbage collections.
My main problem is that I see the counters increasing rapidly but don't have a clue where and why so many objects get created -- at least they don't get leaked. Most likely the main cause are these hidden LINQ closures, iterator implementation classes and hidden classes created by LINQ expressions.