Managed Code can't have memory leaks, right?

One of the axioms of working with managed code is that since you’re using managed code, you don’t have to worry about memory leaks.

This can’t be further from the truth. It’s totally possible to write code that leaks memory, even with managed code.

The trick is when you realize that your code can leak, even if the CLR hasn’t.

Here’s some code I wrote earlier today that leaks memory, for example:

            public static void AppendXxxNodes(XmlNode Node)
{
if (Node.SelectSingleNode("Xxx") == null)
{
if (Node.HasChildNodes)
{
foreach (XmlNode childNode in Node.ChildNodes)
{
XmlNode systemProtectionNode = Node.OwnerDocument.CreateElement("Xxx");
Node.AppendChild(systemProtectionNode);
}
}
}
}

The problem is of course that Node.AppendChild adds an entry to the ChildNode array, so the foreach node is effectively in an infinite loop. The CLR hasn’t leaked any memory; it knows where all the objects are. But my app leaked memory just the same.

I had this happen to me in the Exchange NNTP server many years ago in unmanaged code. I had a credentials cache that was used to hold onto the logon information for users connecting to the NNTP server. But there was a bug in the cache that prevented cache hits. As a result, every user logon caused a new record to be added to the credentials cache.

Now, the memory didn’t “leak” – when we shut down the server, it quite properly cleaned out all the entries in the credentials cache. My code didn’t forget about the memory, it just was using too much of it.

There are LOTS of ways that this can happen, both obvious (like my example above), and subtle.

Edit: Fixed stupid mistake :)