Hunting down the missing calls to Dispose()
Today I had five different meetings. Yes, that’s how my average day looks like. Between these meetings there are slots of time I use to read and write e-mail and do something I call "real work" ;-) The interesting discovery for today was that I found a pattern in our code base where we create number of different objects implementing IDisposable interface and we accidentally forgot to call Dispose() method on them. As almost anyone traveling in the managed world knows, this means that the objects won’t be properly cleaned up till garbage collection kicks in at some point which because of the nondeterministic nature of garbage collection may happen whenever CLR decides it’s necessary.
Why do I care ;-) Well, because I work on the server product and we really-really-really want everything cleaned up in timely fashion to keep the working set as low as possible. When working set keeps increasing or handle count keeps growing then we start getting pretty nervous around here.
The typical code pattern may look like this:
{
...
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
//
// Do something with 'sw', but never call 'Close()' when finished.
//
}
Everyone knows the saying "Where There's Smoke There's Fire". For the practical applications I’ll borrow the quote from Glenford J. Myers’s "The Art of Software Testing" (page 15):
"The probability of the existence of more errors in a section of a program is proportional to the number of errors already found in that section."
So, if you’ll ask me what I’ll be doing tomorrow between meetings then the answer is that I’ll be checking the related assemblies for the similar patterns ;-)