Andreas Grabner has been helping companies improve their application performance for 15+ years. He is a regular contributor within Web Performance and DevOps communities and a prolific speaker at user groups and conferences around the world. Reach him at @grabnerandi

.NET Performance Analysis: A .NET Garbage Collection Mystery

Memory Management in .NET is a broad topic with a lot of “mysteries” that come with it. Heavy memory usage as well as frequent allocations affect the performance of your application because lots of time is spent by the Garbage Collector to free up space in the individual Heap Generations.Its a good practice to monitor your applications memory behavior. Several blog entries exist that describe which performance counters to analyze – here is one that describes the common .NET Performance Counters (including those for memory): .NET Performance Counters.

There are 4 different performance counters per .NET Process that tell us something about the GC Activity:

# Gen 0 Collections

# Gen 1 Collections

# Gen 2 Collections

% Time in GC

The first 3 measures give us the total count of collections that happened in the individual generation since the process started. % Time in GC tells the time that was spent by the GC since the end of the last GC run. Based on best practices this number is good under 10% with occasional spikes above that. If you however see more than 50% of time spent in GC you should drill into that problem.

Mystery with large 2nd Gen Heap

I created a sample ASP.NET application with a built-in memory leak. I ran it on the .NET 3.5 SP1 Framework and hosted the application in the Visual Studio WebDev.WebServer. I wanted to test out if the .NET Performance counters actually provide meaningful data. My memory leak creates several thousands objects in a background thread on a one second interval – putting them all in a static ArrayList so that they wont be collected.

The following illustration shows the memory graph of my app.

.NET Heap Counters showing Memory Leak

The graph shows the constantly growing 2nd Generation Heap – caused by my memory leak. As you can see from the graph above – I stopped my memory leak from creating new objects at about 12:50. Until that time I also saw the number of GC Collections constantly rising. These counters also came to an hold at 12:50 as the following graph shows:

.NET GC Collection Counters

I also expected the % Time in GC to come down when stopping producing new objects. It however turned out that – despite no new objects were allocated – this counter remained on a very high level:

.NET % Time in GC

It’s a mystery to me why the % in GC remained above 60% in my test scenario. It might be due to the fact that I crossed a certain memory usage threshold which makes the GC run more often. It might also be due to the fact that I created more than 1 million objects and that this is a threshold the GC has problems with. Another explaination is that the counter might got screwed up and is no longer delivering accurate values.

Conclusion

Do not only check your heap counters. Also watch the activity of your Garbage Collector which gives you an indication about how your application is allocating memory. Follow the best practices in terms of the thresholds of these counters and start analyzing the internals of your applications memory management in case you experience unusual behavior.

Andreas GrabnerAndreas Grabner has been helping companies improve their application performance for 15+ years. He is a regular contributor within Web Performance and DevOps communities and a prolific speaker at user groups and conferences around the world. Reach him at @grabnerandi

Comments

Hi,
I am a software architect and have been involved in developing Windows Applications that are typically tools to interact with Automotive hardware for activities like Device Configuration/Minotring/Flashing etc, so involves communication with embedded software over protocols like RS232, CAN, LINm Wireless etc..

Lately there is a customer whos is very pessimistic about using .Net for making such applications as he has the strong notion that .Net Garbage collector plays spoilsport and interferes with communication timings and peformance and hence is pusing for a very large scale automation application to be done in VC++, and not using all the other benefits of .Net

Can you please help provide some direction or links to articles/papers that have analysed .Net Garbage collector from this perspective, and if its really a problem using it in critical communication intensive applications ?
I think otherwise and believe that if proper guidelines and practices are followed to avoid GC bottlenecks, its not a problem. But I have to prove the same with enough data and statistics.

We have experienced memory problems with our .NET based web applications. Our lead programmer prefers working with .NET and that is part of the reason we haven’t switched over to a different development platform. Is one potential solution to the memory issue with .NET to have our own dedicated server or network?
______________________________mobile app platform

Hi there,I enjoy reading through your article post, I wanted to write a little comment to support you and wish you a good continuation All the best for all your blogging efforts.How To Make Birthday Cake

[…] is that we need to identify how our GC activity looks like. I’ve covered this already in my previous blog post. There are different performance counters available – both in Java and .NET – that you can monitor. […]