At work, we’ve been running PSR tests against our primary application. Last night, the application (which runs as a windows service), was on an obvious spiral into the drain of despair. The memory was steadily increasing. When it reached 1.5 gigs, the application stopped responding altogether.
That’s not good.
We were going to just not say anything and hope for the best, but the more level headed of us thought that maybe we should take a look. I was completely against it and wanted to sacrifice a goat instead, but I was overruled. (I seem to get overruled every time I want to sacrifice animals.)
I started by reviewing the code. I found some connection objects that weren’t being properly cleaned up. I ordered 50 verbal lashes for the offending perps, but moved on. It wasn’t significant enough to be the memory leak, but did sprout an emotional leak in the bowels of my soul. (Please, just use the using clause. That’s all I ask.)
But I digress. Today, we ran ANTS against it to see where all that memory was all going. It didn’t help, which is unusual.
So, we did it the old fashion way. We started commenting things out of the main method to find which one was the problem. The object does:
- Receives an xml message
- Removes duplicate nodes
- Calls a stored procedure to get more information for each of the nodes
- Does an Xslt Transform
- Publishes the message via WCF
Of all the things there, I was most suspicious of the WCF client and least suspicious of XSLT. Imagine my chagrin when it turned out to be the XSLT method.
XslCompiledTransform transform = new XslCompiledTransform(true);
using (XmlReader xmlReader = new XmlTextReader(xsltFile))
The problem is the TRUE parameter when the object is instantiated. If you remove it, or change it to false, then everything is stable.
This is a surprisingly large bug. How can something as fundamental as the boolean value TRUE take down an application like that? Shouldn’t someone have tested that the booleans work properly before shipping? The very foundations of computing are based on boolean values; bits are either on or off… yes or no… 1 or 0. This isn’t rocket science! How can Microsoft ship a product that doesn’t fully support the word true?
I haven’t been this bothered about the .Net framework since I learned that the number 0 is also broken. Every time I try to divide any number by it, it breaks with some illogical math error (can’t divide by zero?). I can’t say that I’ve tried to divide every number, but I did get the vast majority. .. let’s just say that I’ve tested the theory enough times to be convinced that it is a problem.
I really love .NET and will continue to use it without reservation. But, the tough lesson is that you can’t take it for granted, especially if your logic is based on evaluations of some sort. Now that we’ve identified its limitations, we can use it more effectively.
If the problem was elsewhere… let’s say, if the problem were in the XslCompiledTransform object rather than the word true, that would be more understandable. Then we might be able to conclude that “XslCompiledTransform in debug mode leaks more than the Bush administration”. That’s something we could get our head around and come to terms with… But a broken true!? Dissapointing.