DEFINITION A memory leak is the gradual deterioration of system performance that occurs over time as the result of the fragmentation of a computer's RAM due to poorly designed or programmed applications that fail to free up memory segments when they are no longer needed.
The system can have a myriad of symptoms that point to a leak, though: decreased performance, a slowdown plus the inability to open additional programs, or it may freeze up completely.
Causes of Memory Leaks Using Unwanted Object Reference: These are the object references that are no longer needed. The garbage collector is failed to reclaim the memory because another object still refers to that unwanted object. Using Long-live Static Objects: Using static objects also leads to a memory leak.
Memory leaks don't result in physical or permanent damage. Since it's a software issue, it will slow down the applications or even your whole system. However, a program taking up a lot of RAM space doesn't always mean its memory is leaking somewhere. The program you're using may really need that much space.
The best explanation I've seen is in Chapter 7 of the free Foundations of Programming e-book.
Basically, in .NET a memory leak occurs when referenced objects are rooted and thus cannot be garbage collected. This occurs accidentally when you hold on to references beyond the intended scope.
You'll know that you have leaks when you start getting OutOfMemoryExceptions or your memory usage goes up beyond what you'd expect (PerfMon has nice memory counters).
Understanding .NET's memory model is your best way of avoiding it. Specifically, understanding how the garbage collector works and how references work — again, I refer you to chapter 7 of the e-book. Also, be mindful of common pitfalls, probably the most common being events. If object A is registered to an event on object B, then object A will stick around until object B disappears because B holds a reference to A. The solution is to unregister your events when you're done.
Of course, a good memory profile will let you see your object graphs and explore the nesting/referencing of your objects to see where references are coming from and what root object is responsible (red-gate ants profile, JetBrains dotMemory, memprofiler are really good choices, or you can use the text-only WinDbg and SOS, but I'd strongly recommend a commercial/visual product unless you're a real guru).
I believe unmanaged code is subject to its typical memory leaks, except that shared references are managed by the garbage collector. I could be wrong about this last point.
Strictly speaking, a memory leak is consuming memory that is "no longer used" by the program.
"No longer used" has more than one meaning, it could mean "no more reference to it", that is, totally unrecoverable, or it could mean, referenced, recoverable, unused but the program keeps the references anyway. Only the later applies to .Net for perfectly managed objects. However, not all classes are perfect and at some point an underlying unmanaged implementation could leak resources permanently for that process.
In all cases, the application consumes more memory than strictly needed. The sides effects, depending on the ammount leaked, could go from none, to slowdown caused by excessive collection, to a series of memory exceptions and finally a fatal error followed by forced process termination.
You know an application has a memory problem when monitoring shows that more and more memory is allocated to your process after each garbage collection cycle. In such case, you are either keeping too much in memory, or some underlying unmanaged implementation is leaking.
For most leaks, resources are recovered when the process is terminated, however some resources are not always recovered in some precise cases, GDI cursor handles are notorious for that. Of course, if you have an interprocess communication mechanism, memory allocated in the other process would not be freed until that process frees it or terminates.
I think the "what is a memory leak" and "what are the effects" questions have been answered well already, but I wanted to add a few more things on the other questions...
How to understand whether your application leaks
One interesting way is to open perfmon and add traces for # bytes in all heaps and # Gen 2 collections , in each case looking just at your process. If exercising a particular feature causes the total bytes to increase, and that memory remains allocated after the next Gen 2 collection, you might say that the feature leaks memory.
How to prevent
Other good opinions have been given. I would just add that perhaps the most commonly overlooked cause of .NET memory leaks is to add event handlers to objects without removing them. An event handler attached to an object is a form of reference to that object, so will prevent collection even after all other references have gone. Always remember to detach event handlers (using the -=
syntax in C#).
Does the leak go away when the process exits, and what about COM interop?
When your process exits, all memory mapped into its address space is reclaimed by the OS, including any COM objects served from DLLs. Comparatively rarely, COM objects can be served from separate processes. In this case, when your process exits, you may still be responsible for memory allocated in any COM server processes that you used.
I would define memory leaks as an object not freeing up all the memory allocated after it has completed. I have found this can happen in your application if you are using Windows API and COM (i.e. unmanaged code that has a bug in it or is not being managed correctly), in the framework and in third party components. I have also found not tiding up after using certain objects like pens can cause the issue.
I personally have suffered Out of Memory Exceptions which can be caused but are not exclusive to memory leaks in dot net applications. (OOM can also come from pinning see Pinning Artical). If you are not getting OOM errors or need to confirm if it is a memory leak causing it then the only way is to profile your application.
I would also try and ensure the following:
a) Everything that implements Idisposable is disposed either using a finally block or the using statement these include brushes, pens etc.(some people argue to set everything to nothing in addition)
b)Anything that has a close method is closed again using finally or the using statement (although I have found using does not always close depending if you declared the object outside the using statement)
c)If you are using unmanaged code/windows API's that these are dealt with correctly after. (some have clean up methods to release resources)
Hope this helps.
If you need to diagnose a memory leak in .NET, check these links:
http://msdn.microsoft.com/en-us/magazine/cc163833.aspx
http://msdn.microsoft.com/en-us/magazine/cc164138.aspx
Those articles describe how to create a memory dump of your process and how to analyze it so that you can first determine if your leak is unmanaged or managed, and if it is managed, how to figure out where it is coming from.
Microsoft also has a newer tool to assist with generating crash dumps, to replace ADPlus, called DebugDiag.
http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With