views:

44

answers:

1

I have the following function in a COM dll (C#, .NET framework v2):

public void Leak(object jsObject) {
    Type comType;
    IDispatch disp = (IDispatch)jsObject;
    disp.GetTypeInfo(0, 0, out comType); // this line causes the leak
    Marshal.FinalReleaseComObject(disp);
    Marshal.FinalReleaseComObject(jsObject);
    disp = null;
    jsObject = null;
    GC.Collect(); GC.WaitForPendingFinalizers();
}

When calling this function repeatedly from a JScript, it leaks lots of memory:

var util = new ActiveXObject('MyLeakyCOM.MyLeakyCOM');

for(var i = 0; i < 1000; i++) {
    util.Leak({});
}

I've already tried to release the object with while(Marshal.ReleaseComObject(disp) > 0) {} but also no luck.

A: 

I'm a C++ guy rather than a C# guy, but it strikes me that you should also be releasing comType:

Marshal.FinalReleaseComObject(comType);

The ITypeInfo object is a proper COM object and it's AddRef will have been called by the implementation of GetTypeInfo.

Phil Booth
Unfortunately this doesn't work: It complains about the object not being an instance of System.__ComObject or something derived from that.I've also tried `Marshal.Release(Marshal.GetIUnknownForObject(comType));` - while that doesn't cause an exception it doesn't do anything notable.
ThiefMaster
Using ITypeInfo instead of Type also didn't help - it causes the same exception.
ThiefMaster
Hmmm. Again, I'm not a C# guy so this may be off beam, but can you call `Release` directly? Something like `((IUnknown)comType).Release();` or similar?
Phil Booth
Nope.. but looks like the leak is caused by some assymbly which is auto-generated. Using http://www.eggheadcafe.com/software/aspnet/30919888/introspecting-com-object-in-c.aspx it's less leaky. However, i've decided to change my code so it doesn't need to iterate over a JS object - should've done that much earlier then i wouldn't have wasted half a day with debugging the leak..
ThiefMaster