15.01.2013 Views

Foundations of Programming - Karl Seguin

Foundations of Programming - Karl Seguin

Foundations of Programming - Karl Seguin

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!