Foundations of Programming - Karl Seguin
Foundations of Programming - Karl Seguin
Foundations of Programming - Karl Seguin
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Chapter 7 - Back to Basics: Memory<br />
Managed Memory Leaks<br />
We already saw an example <strong>of</strong> what a memory leak looks like in C. Basically, if C# didn't have a garbage<br />
collector, the following code would leak:<br />
private void DoSomething()<br />
{<br />
string name = "dune";<br />
}<br />
Our stack value (a pointer) will be popped <strong>of</strong>f, and with it will go the only way we have to reference the<br />
memory created to hold our string. Leaving us with no method <strong>of</strong> freeing it up. This isn't a problem in<br />
.NET because it does have a garbage collector which tracks unreferenced memory and frees it. However,<br />
a type <strong>of</strong> memory leak is still possible if you hold on to references indefinitely. This is common in large<br />
applications with deeply nested references. They can be hard to identify because the leak might be very<br />
small and your application might not run for long enough<br />
Ultimately when your program terminates the operating system will reclaim all memory, leaked or<br />
otherwise. However, if you start seeing OutOfMemoryException and aren't dealing with abnormally<br />
large data, there's a good chance you have a memory leak. .NET ships with tools to help you out, but<br />
you'll likely want to take advantage <strong>of</strong> a commercial memory pr<strong>of</strong>iler such as dotTrace or ANTS Pr<strong>of</strong>iler.<br />
When hunting for memory leaks you'll be looking for your leaked object (which is pretty easy to find by<br />
taking 2 snapshots <strong>of</strong> your memory and comparing them), tracing through all the objects which still hold<br />
a reference to it and correcting the issue.<br />
There's one specific situation worth mentioning as a common cause <strong>of</strong> memory leaks: events. If, in a<br />
class, you register for an event, a reference is created to your class. Unless you de -register from the<br />
event your objects lifecycle will ultimately be determined by the event source. In other words, if ClassA<br />
(the listener) registers for an event in ClassB (the event source) a reference is created from ClassB to<br />
ClassA. Two solutions exists: de-registering from events when you're done (the IDisposable pattern is<br />
the ideal solution), or use the WeakEvent Pattern or a simplified version.<br />
Fragmentation<br />
Another common cause for OutOfMemoryException has to do with memory fragmentation. When<br />
memory is allocated on the heap it's always a continuous block. This means that the available memory<br />
must be scanned for a large enough chunk. As your program runs its course, the heap becomes<br />
increasingly fragmented (like your hard drive) and you might end up with plenty <strong>of</strong> space, but spread out<br />
in a manner which makes it unusable. Under normal circumstances, the garbage collector will compact<br />
the heap as it's freeing memory. As it compacts memory, addresses <strong>of</strong> objects change and .NET makes<br />
sure to update all your references accordingly. Sometimes though, .NET can't move an object: namely<br />
when the object is pinned to a specific memory address.<br />
<strong>Foundations</strong> <strong>of</strong> <strong>Programming</strong> Copyright © <strong>Karl</strong> <strong>Seguin</strong> www.codebetter.com<br />
61