Reputation: 11953
I have a fairly complex F# application, and I use a F# script to check its performance using the #time
directive. The idea is that I run the script after changes to the code to keep track of performances and avoid introducing speed or memory problems.
The report I was getting was something like this:
Real: 00:00:02.908, CPU: 00:00:02.948, GC gen0: 237, gen1: 3, gen2: 1
but after the last change I get this:
Real: 00:00:03.058, CPU: 00:00:03.057, GC gen0: 262, gen1: 262, gen2: 0
and I have some trouble figuring out what's going on.
More generation 1 garbage collection means (?) that there are more long-lived object that survive garbage collection in generation 0 - but why the sudden jump from 3 to 262? And why the number of garbage collection on generation 0 and 1 are identical? If for some reason after the code changes there are more long-lived objects I would have expected something like:
Real: 00:00:02.908, CPU: 00:00:02.948, GC gen0: 212, gen1: 54, gen2: 1
i.e. the total number of garbage collected objects being similar but with more on generation 1.
Or am I totally misunderstanding those numbers (I could not find a description in the documentation)?
UPDATE
As pointed out in the comments I totally misunderstood the numbers: they are the number of garbage collections executed for each generation, not the number of objects.
Having said that I am even more puzzled: it seems that my application put the memory in such a state that every generation-0 garbage collection triggers also a generation-1 one, and I cannot imagine what this state could be. I tried various test programs to replicate such behavior without luck.
I still have to try the profilers as suggested in the comments and pad's answer.
UPDATE 2
I tried the CLR profiler as suggested in the comments - to do it I converted my F# script into a program and run it from the profiler.
The report I get is completely different from the #time
one - garbage collections:
Mistery - strage side-effect of using FSI.exe compared with a stand-alone program? Bug in #time
?
Upvotes: 1
Views: 2041
Reputation: 41290
.NET GC is a three-generation GC. As John Palmer pointed out, the last three numbers are the number of collections run at these generations. Bigger numbers in gen1
and gen2
often indicate bad performance since GC has to mark those unused objects again and again in each garbage collection process. For more in depth introduction of .NET GC, take a look at this nice article.
Here are a few suggestions:
Upvotes: 2