Andreas Grabner About the Author

Andreas Grabner has been helping companies improve their application performance for 15+ years. He is a regular contributor within Web Performance and DevOps communities and a prolific speaker at user groups and conferences around the world. Reach him at @grabnerandi

SharePoint: Identifying memory problems introduced by custom code

SharePoint is a great platform that makes it easy to customize the portal view for users to their individual needs. Many times though the out of the box Features, Lists and Web Parts are not enough. So you either buy 3rd party extensions or you build your own. One specific problem area with SharePoint is memory. Especially when dealing with the SharePoint Object Model you can easily run into memory leaks. Why that? Isn’t it all managed code and shouldn’t the Garbage Collector take care of unused object? Well – that’s only partial true for SharePoint.The SharePoint Object Model explained

When you write your own Web Parts and if you want to access SharePoint data you have to use the SharePoint Object Model. The model provides an extensive list of managed objects to query your SharePoint webs, sites and lists. The core of SharePoint however is mostly implemented in native code which is wrapped by certain classes. Hristo Pavlov wrote a great article that explains the special wrapper class SPRequest which plays a very central role in the SharePoint Object Model.

Disposing SPWeb and SPSite

As you can read from Hristo’s and other blogs – it is essential to call Dispose or Close on certain objects that you get returned when working with the SharePoint Object Model. If you don’t do it – the Garbage Collector will not clean those objects which will lead to a memory issue over the long run. Not only is managed memory not freed – it’s mainly unmanaged memory that is referenced by those managed wrapper objects.

How to identify memory problems

The first thing you have to do is find out whether you have a memory problem or not. If your application pools constantly recycle because you exceeded your memory limit then its very likely that you have a memory issue. You can use a monitoring tool like Windows Performance Logs and Alerts to monitor the performance counters of your w3wp.exe worker processes. Make sure you look at Heap Size Gen0, Gen1, Gen2, Large Object Heap as well as GC Activations for Gen0, Gen1 and Gen2. Managed objects are allocated in Generation 0 are being promoted to higher generations when they could not be freed by a GC Run. If you see your Gen2 (which is the highest generation) constantly growing – you know you have objects that could not be freeded by the GC because somebody is still holding references to them. Here is a memory graph taken with dynaTrace:

Monitoring Gen0, Gen1 and Gen2 of the .NET Process

Monitoring Gen0, Gen1 and Gen2 of the .NET Process

How to locate Memory Problems

Knowing that there is a memory problem is the first step. Now its time to figure out where the problem actually is. In this blog I want to focus on those SharePoint classes that we know are very likely a problem when not disposed or closed. The approach that I will use can also be applied to any other .NET class.

dynaTrace offers different types of Memory Dumps:

  • Simple allows you to get an overview of the number of instances of every individual class on the heap
  • Extended allows you to analyze each object on the heap including size and dependencies to other objects. This allows you to walk the referrer tree to find out which objects are holding a reference to an object and which objects are referenced by a particular object
  • Selective allows you to selectively focus on particular classes. Find out which objects are still on the heap and where those objects have been allocated

As I know which classes we want to selectively monitor I start with defining a Memory Sensor Rule:

Memory Sensor Rule for SPWeb and SPSite

Memory Sensor Rule for SPWeb and SPSite

The next step is that I schedule a selective memory dump that runs every couple of minutes. I can then take these dumps and compare them to find out if there are really objects that steadily grow.

Comparing Multiple=

Comparing Multiple Dumps shows growing SPSite objects

We can now take a closer look at the last dump and analyze the objects of SPWeb and find out which method created the individual instances:

Selective Memory Dump showing individual instances

Selective Memory Dump showing individual instances

We can see that OpenWeb created those 13 remaining instances. The final step allows us to see where OpenWeb was called in context of a single request to a SharePoint page. We can see the call to OpenWeb and the object allocation in the PurePath:

OpenWeb and Object Instantiation in context of the SharePoint request

OpenWeb and Object Instantiation in context of the SharePoint request

We now know that the LookupWebPart is calling OpenWeb in its RenderNormal method. OpenWeb returns a new instance of SPWeb that we need to explicitely Dispose or Close.

Conclusion

You want to avoid memory leaks which lead to frequent recycling of the application pool worker processes. The impact is slower performance, potential loss of data and lower user satisfaction with your customized SharePoint solution. Avoiding can be done by following best practices and common coding guidlines. In case there are memory leaks that made it to the final product you want to make sure to find them. The above described approach is one that enables quick and easy analysis of leaking code.

Comments

  1. This was a big deal for us – we wrote a custom menu system that wasn’t disposing of SPWebs and was a disaster performance wise, a good post – cheers :D

Trackbacks

  1. [...] where SPDisposeCheck tool may become handy. On a broader scope, identifying memory problems is a great article. this is done by the .net garbage collector and actually the .NET framework does [...]

Comments

*


− 4 = two