I have a C# program that accesses a COM Interface to a piece of simulation software called Aspen Plus. I have a very strange memory leak.
When I need to get the result values out of the simulation, I run a series of calls like this, in some cases the variable returned might be null, so I insert a check for that. Then I use FinalReleaseComObject to clean up the COM references.
public override ValueType recvValueFromSim<ValueType>(string path) {
Happ.IHNode tree = this.Aspen.Tree;
dynamic node = tree.FindNode(path);
ValueType retVal = default(ValueType);
if (node != null && node.Value != null) {
retVal = node.Value;
}
Marshal.FinalReleaseComObject(node);
Marshal.FinalReleaseComObject(tree);
node = null;
return retVal;
}
Unfortunately, the above code leaks a lot. It leaks 2MB per simulation. At first I thought the Garbage Collector would eventually run and clean it up, but no dice. After running a couple of hundred simulations, I ran out of memory.
The bizarre thing is, the below code works fine and doesn't leak. I didn't like it, because using catch to check for null references seems like bad form, but this doesn't leak.
public override ValueType recvValueFromSim<ValueType>(string path) {
ValueType node;
try {
node = this.Aspen.Tree.FindNode(path).Value;
return node;
} catch {
return default(ValueType);
}
}
Why doesn't it leak? Does anybody know? The belies why I thought I knew about temporary references and releasing COM objects.