'Why does Silverlight leak memory when using COM?

We discovered this issue when hosting a legacy COM component in our Out Of Browser Silverlight application, first thinking it was an issue with our COM component.

Narrowing it down to hosting the most basic COM component imaginable still had the memory leak, however. This COM component used for testing is written in .NET, and simply sends events back to the Silverlight application every time a timer fires. Each event contains a single string only.

When running the Silverlight application, the process memory usage keeps growing. Profilers show no increase in managed memory, indicating that there's a leak in the Silverlight runtime / COM implementation.

Has anyone else seen this issue, and if so, have you been able to work around it?

Edit: Repro project now available at http://bitbucket.org/freed/silverlight-com-leak



Solution 1:[1]

Looking at your code, the string you pass back & forth is (11 characters + terminating zero) = 24 bytes in unicode. In COM Automation, BSTR are used wich adds 4 bytes for the leading pointer (32-bit), and you multiply that by 10000, wich is 10000 * 28 = 280000 bytes.

It means every millisecond (the timer's value is 1) you will allocate a lot of memory, and in .NET a 280000 bytes chunk will probably be allocated in the large object heap (> 85000 bytes). The result of hitting hard on the LOH is most of the time... problems with memory, as seen here for example: Large Object Heap Fragmentation

This is maybe something you should check. One simple thing to test is to reduce the size of your BigMessage. You can also dive in deep with WinDBG: http://blogs.msdn.com/b/tess/archive/2008/08/21/debugging-silverlight-applications-with-windbg-and-sos-dll.aspx and check what's really going on under covers.

Solution 2:[2]

Make sure the COM component is freeing any strings it allocates.

Solution 3:[3]

Not familiar with Silverlight, but another possible cause of interop headaches is event handling: http://www.codeproject.com/KB/cs/LingeringCOMObjects.aspx

Solution 4:[4]

Could it be that there are native resources not garbage collected? Maybe this is one of the very few cases where calling GC.Collect may be of benefit. Interesting reading here

Just for test you could call GC.Collect a couple (or even three times) and see what happens (I can't believe I'm actually suggesting this...).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Jeff Yates
Solution 3 hythlodayr
Solution 4 Glorfindel