COM objects need tight leash

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.

6 Comments

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

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

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

  • 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

  • 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.

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

Comments have been disabled for this content.