Iris Classon
Iris Classon - In Love with Code

Stupid Question 48: What is a memory leak, and how common are memory leaks in C# apps?

[To celebrate my first year of programming I will ask a ‘stupid’ questions daily on my blog for a year, to make sure I learn at least 365 new things during my second year as a developer]

How common are memory leaks in c# apps

With the garbagecollector in C# I haven’t really paid but attention to this ‘phenomena’ (not a really a phenomena but rather a logical result). When I did an iPhone application I used a cross platform tool, and in the forums there was a lot of debate that memory was poorly handled and there was a lot of memory leaks (I assume that is fixed now, but who knows). It got me a bit curious, but as always, it got pushed to the back of my mind for later thinking. I keep a list of all my questions, and must-look-this-up things. And as I reviewed the list today I came across these three notes:

What is the definition of a memory leak? //This note was from my first month programming

My definition I had scribbled down next to the question:

Applications obtain memory for temporary use when they run, and they are supposed to return/ let go of this temporary memory when it is not needed anymore. There isnt an infinitive amount of memory available, and if the applications doesn’t free up the memory it has used you have yourself a memory leak. The application doesn’t use the memory, but that bit of memory is ’taken’. Over time even tiny memory leaks can have a big impact on an application.

How common are memory leaks in c# apps?

I actually don’t know! I would love to pass on this question to more experienced devs, I haven’t tested my applications with any memory profiler tools yet (but I’ll give JustTrace from Telerik a go next week on a couple of apps since I already have it installed).

What are some common culprits? (Would love some examples if you have :) )

Comments

Leave a comment below, or by email.
Franc
9/22/2012 2:44:51 AM
There are very good tools that can help you spot memory leaks roots in your app, I recently used http://memprofiler.com/

It is a very good tool, and it tells you everything, analyze memory usage and highlight potential memory leak issues. 
Alex
9/22/2012 3:22:38 AM
Very good question! Have you tried to find an answer on stackoverflow.com? Maybe you can ask this great man @jonskeet about this. 
Iris Classon
9/22/2012 3:34:16 AM
Reply to: Alex
Yes, of course I have :) I'm a frequent user of SO, both asking and answering (more asking though LOL).

I always spend some time searching for an answer before posting here- so people can always safely assume I've read the first ten pages of google search results and the majority of Q's on SO. 

But I have not asked Jon directly. I'll see if I can lure him to answer here :D 
Iris Classon
9/22/2012 3:34:51 AM
Reply to: Franc
Sounds like a must try, thank you for the tip! 
Ian Quigley
9/22/2012 4:58:32 AM
In theory, there shouldn't be any memory leaks if you keep in the "managed" safe domain. You can run out of memory, if everything you keep in memory is essential. Normally this isn't something a c# dev worries about.Not like in the old days of C/C++ 
Bill Greer
9/22/2012 5:03:53 AM
So Ian, if I have a C# app with Active X controls, I could get into trouble?  How do I stay safe with AX controls?   ...... Great question Iris. 
Atul Gupta
9/22/2012 5:56:28 AM
While the general expectation is that due to managed code, there will be no mem leaks, there are various ways things can go wrong. first thing to clealry understand is what mem leak means. A program when terminated releases all the memory, so the leak is only as long as the program is running. It essentially refers to objects being still in memory when you expected them to have gone or recovered by GC

1. use of objects that need you to invoke Dispose, but you miss calling it. this typically means leaks to internally called/retained objects, mostly COM
2. adding event handlers, but missing disconnecting from them when done. this causes objects to stay in memory as they have a reference and GC cannot collect them
3. there are cases when code is compiled and creates dynamic assemblies in memory. since assemblies cannot be unloaded (only app domains can), these can also result in leaks

there are tools that help with this as others have mentioned. the main symptom to watch out for is the program memory keeps increasing or you get outofmemory exception when you won't expect one to happen. if you know how to use Windbg, that's the best to work with

very interesting blog series by Tess here - http://blogs.msdn.com/b/tess/ 
Joep Beusenberg
9/22/2012 6:37:12 AM
Most C# apps have memory leaks to some degree. But it doesn't tend to go too fast, so you rarely notice it. I started to notice it at first when I developed a big WPF app that opened multiple windows and people started to use the app for weeks without restarting the app.

The biggest problem lies with objects that reference each other. For example A references B, B references C, and C references B. No problem yet: three objects exist, and they should. But what happens when A loses it's reference to B? Since B is still referenced by C, it won't be finalized. And because C is referenced by B, that too will not be finalized. And that includes all references B and C have.

This is a situation that occurs more often than you think: hierarchical data with a reference to its parent object is a good candidate. But also non-static events fall in this category: the object references the event handler, and the event handler references the object.

(I read somewhere the problem with events is solved in 4.5 by using WeakReferences, but I haven't yet confirmed this actually is true. I believe it was limited to WPF, but I'm not sure of that either.)

WeakReferences can solve the problem above: if B references C and C has a WeakReference to B, B will get finalized as the WeakReference doesn't count for the garbage collector. And then C isn't referenced anymore, so that one too will get disposed. 
Morten
9/22/2012 7:00:45 AM
The by far most common memory leak I see in C# is via event handlers where memory intensive instances (usually xaml controls/pages) listen to event on objects that are long lived or static. 
Ie in a navigation scenario when navigating to a page that page starts listening to an event that's on your application state. When you navigate to a new page, the previous page cannot be collected because it's still hooked to the app state which naturally is still alive. So remember to both hook AND unhook in navigated to/from or loaded/unloaded. 
James Kovacs
9/22/2012 4:12:40 PM
Yes, managed apps can leak memory. I wrote an article about it for MSDN Magazine 5 years ago and the information is still relevant today. HTH.

Debug Leaky Apps: Identify And Prevent Memory Leaks In Managed Code 
Ladislau Radu Nagy
1/21/2013 1:21:38 PM
Well, the topic is too big to form an opinion in one comment.
When working with C# you have to consider the multi generation garbage collection. With that in mind you should always call .Dispose() on resources(i.e.: file, database connection, network connection, etc.) before dereferencing them, in the moment you have finished your work with them(or use the using() syntactic sugar, keep in mind that in .NET 2.0 you should call dispose and dereference, even with this syntactic sugar).
Memory leaks usually appear when the GC can't deallocate the reserved space, because something is still referencing it. 
Another reason is memory pressure, you are allocating memory too fast, and the GC can't keep up with you, plus the memory zone is still referenced. 


Last modified on 2012-09-19

comments powered by Disqus