COM objects need tight leash

Published 22 June 05 10:48 AM | madsn

When a customer suddenly reports memoryusage on their Sharepoint Server of 300mb increase an hour you tend to show up pretty quick.

This happened yesterday. After having installed a range of updates and patches to their server software, something in the w3wp process caused extensive memoryusage, eventually causing the process to terminate. According to the customer the process seemed to terminate (and recycle) at about 370mb, but after installing the latest Microsoft Office updates the memory grew all the way up to the maximum configured limit of 800mb.

I started analyzing the applications running under the w3wp process and got great help from the .NET Memory Profiler from Scitech. My initial hunch was that one or more of the COM interop parts of the solution was to blame.

After locating the varous COM classes indirectly involved in the Sharepoint / ASP.NET solutions running under the w3wp process the profiler showed that one of the COM objects was instantiated in large numbers in high frequencies. My guess was that the .NET Garbage Collector was cleaning up the managed references (the runtime callable wrapper - RCW) but not the COM objects themselves. I've seen this earlier in working with the Sharepoint object model and the Office Interop components.

The solution was to ensure a real cleanup after the use of the RCWs like this (updated to reflect my actual non-simplified implementation):

COMInteropComponent.RCWClass rcw = null;


try
{

   rcw = new COMInteropComponent.RCWClass()

   // Do some work with the rcw object
   rcw.DoSomeWork();

}
finally
{
   // Clean up COM
   if(rcw != null)
   {
      while(Marshal.ReleaseComObject(rcw) != 0){}

      // Set null and let the GC handle the managed reference
      rcw = null;
   }
}

This stopped the memory leak and the server has been running with stable memoryusage for more than 12 hrs. The reason why the use of this component started causing a memory leak only after patching up the server is not known, but anyways the moral of the story is to always handle unmanaged references with care.

Comments

# Joe said on June 22, 2005 05:43 AM:

To be completely robust, use a try/finally to make sure ReleaseComObject is called even if there is an exception.

# Mads said on June 22, 2005 06:23 AM:

Yep, this is excactly what I did. I've updated the snippet to include it.

# Sean Chase said on June 22, 2005 12:15 PM:

Interesting. I get what you are doing, but in your sample, rcw would be out of scope in the finally block thought, right?

# Ed Richard said on June 23, 2005 11:10 AM:

I have the same problem where I need to update many document library item (thousands), I'm calling Addy Santo's WssDal, which as far as I can tell just uses the Sharepoint object model. Any thoughts on where to start looking?
Do you maybe have an idea regarding the actual cause?

Thanks,
Ed Richard

# Mads said on June 24, 2005 03:07 AM:

If the WssDal component doesn't clean up properly it's little you can do. I wrote my own mass-doclib-updater, thus can I control my own memory management.

Try profiling the application you're using and suggest for the developer which objects you think he should revise and tighten memory management for.

# Ed Richard said on June 24, 2005 09:52 AM:

Thanks, care to do a post about the code for that doclib adapter Mads?

Leave a Comment

(required) 
(required) 
(optional)
(required) 

This Blog

<a name="MyWork">!My work!</a>

Funstuff

Goodies

MSCRM Blogs

Sharepoint

Useful reading

Weblogs

Syndication