
SP 2010: Developing for performance Part 5 - Disposal patterns and tools
๐ก Presently sponsored by: ScriptRunner
Webinar: Azure administration made easy with powershell!
SharePoint 2010 developing for performance article series:
In this series of articles I will briefly introduce you to some key concepts when it comes to developing for performance in our SharePoint 2010 applications.
Related articles in series
- SP 2010: Developing for performance Part 1 - Developer Dashboard
- SP 2010: Developing for performance Part 2 - SPMonitoredScope
- SP 2010: Developing for performance Part 3 - Caching in SharePoint 2010
- SP 2010: Developing for performance Part 4 - Logging
- SP 2010: Developing for performance Part 5 - Disposal patterns and tools
- SP 2010: Developing for performance Part 6 - CSS Sprites
- SP 2010: Developing for performance part 7 - Crunching those scripts
- SP 2010: Developing for performance Part 8 - Control that ViewState
This is part 5.
In SharePoint 2010 (and 2007 for that matter) thereโs a few objects in the APIโs that requires your special attention in order to behave properly. If you do not consider the disposal patterns and rules set forth, your application may very well suffer performance issues. In this article I will briefly touch upon the subject of disposing your SharePoint objects and foremost enlighten how important it is to dispose the objects!
What does Disposing mean and why is it important?
When I deliver training, thereโs always the question about why disposing is important. In SharePoint thereโs valid grounds for saying itโs important to dispose, more than just saying "Itโs best practice". If you donโt properly dispose some of your objects in SharePoint youโll quickly face performance issues since those objects donโt get caught and disposed by the Garbage Collector in a timely fashion as most other objects do in .NET.
What is a "dispose pattern"?
- Read Wikipedia: http://en.wikipedia.org/wiki/Dispose
The Dispose Pattern is the approach used to properly dispose and clean up the resources youโre using in your projects when programming in .NET (or other runtimes). Normally thereโs an automatic garbage collector doing the cleanup for you โ but in certain scenarios (like the ones described later in this article), youโll need to manually dispose your objects.
IDisposable
In Microsoft .NET when an object inherits from the IDisposable interface it means that the Garbage Collector will call the .Dispose() method of that object when itโs no longer used. The Dispose() method in turn calls the Close() method which generally means you should call the .Dispose() method instead of the .Close() method to make sure the objects are properly disposed. Keep reading to see why this is so important!
Why is manual disposal really, really important in SharePoint?
Some of the objects youโre working with heavily in the SharePoint object model (for example the SPWeb and SPSite) are mostly using unmanaged code โ and since the managed part of the code is quite small it doesnโt leave a large memory footprint and hence the Garbage Collector donโt necessarily dispose of that object โ which means that itโll be occupying server resources for a longer time if you donโt manually dispose of those objects.
What happens if I forget to dispose?
Thereโs several things that you may notice in your applications if youโve implemented a solution that are not properly disposing their objects.
- Memory consumption. - The consumption of your server memory may peak and the worker process (w3wp.exe) may consume a lot more memory than it would normally have to consume.
- Application Pool recycling. - If the worker process consumes too much memory, itโll recycle the application pool.
- If youโve got an underperforming application causing overwhelming ย memory consumption the Application Pool will recycle more often.
- Performance issues! - Slow response times
- Timeouts
- Unexpected errors
- Headache - User headache
- Support headache
- Admin headache
- Developer headache (ultimately)
In other words: Make sure youโre properly disposing your objects at all times!
Sandboxed Solutions and Resource Usage โ Think about dispose patterns!
If youโre developing applications for the Sandbox in SharePoint 2010 (User Code Solutions / Sandboxed Solutions) you may be aware of the resource point system that will limit your applicationโs usage of resources on the server. This is a great way to keep the admins calm and developers keen on producing quality code.
A thing to note is that if you donโt correctly dispose your objects they will consume more server resources which in turn would lead to the resource points increasing. If the resource usage reaches the limits set forth by SharePoint for a sandboxed solution โ itโll deactivate it.
In other words: Make sure youโre properly disposing your objects at all times!
Letโs visualize the performance problem!
Okay, so now that Iโve got your attention โ letโs do a quick performance test to see how the process handles the memory if we create the same application with and without disposal patterns in SharePoint.
I created a simple application that will work heavily with the SPSite and SPWeb objects on one of my servers. After hooking up a performance counter and monitoring the memory consumption repeatedly during a few hours of repeated execution it was easy to line down a conclusion which you can see in the chart below.
Performance summary
The following chart displays the same application with and without implementing the dispose patterns in a SharePoint 2010 execution environment.

You can see by the results of the two applications above that when weโre properly disposing our objects thereโs a notable difference in the performance in our application โ and hence the overall server resource usage.
In other words: Make sure youโre properly disposing your objects at all times!
How to: Implement dispose patterns in your SharePoint code
At this point we know itโs very important to dispose our objects in SharePoint โ letโs take a look at how we can do that properly and what tooling and guidelines we can use to help us in this important quest!
Approach 1 โ Manually calling Dispose()
The absolutely most general and simple approach to dispose your objects is to simply call the .Dispose() method of your objects:
SPSite site = newSPSite("http://zimmergren/");
// Do stuff
site.Dispose();
Approach 2 โ Encapsulating the statement in a using() block
A more common approach is to encapsulate the code in a using-block where the object will be automatically disposed when weโre reaching the end of our block.
using (SPSite site = newSPSite("http://zimmergren")) ;
{
// Do stuff
}
Approach 3 โ Utilize a try/finally block
Whenever youโre expecting to catch an exception or somehow might stumble onto exceptions and need to handle them โ a better approach for disposing is to create a try-finally block and dispose the object in the finally-block.
//Sample 1: Without exception handling
SPSite site = null;
try
{
site = new SPSite("http://zimmergren");
// do stuff
}
finally
{
if (site != null) site.Dispose();
}
// Sample 2: With exception handling
SPSite site = null;
try
{
site = new SPSite("http://zimmergren");
// do stuff
}
catch (Exception ex)
{
// Handle the exception
// Possibly send it to the logs
}
finally
{
if (site != null) site.Dispose();
}
Approach 4 โ A mix of the aforementioned approaches
In some scenarios it might be a necessity to mix the aforementioned methods for disposing.
using (SPSite site = newSPSite("http://zimmergren"))
{
foreach (SPSite oSite in site.WebApplication.Sites)
{
try
{
// Do stuff
}
catch (Exception ex)
{
// Log and handle exceptions
}
finally
{
if (oSite != null) oSite.Dispose();
}
}
}
Using SPDisposeCheck.exe to help us check for issues
Itโs one thing to be pro-active and think about the dispose patterns when youโre developing your applications โ but sometimes you canโt cope for every scenario in your complex code. Donโt worry though โ youโve got one of my best friends to help you out with that โ the SPDisposeCheck.exe tool that Microsoft released to check for disposal problems.
Download and install it
Thereโs a new version of the popular dispose-check tool for SharePoint called SPDisposeCheck. You can find it here: http://code.msdn.microsoft.com/SPDisposeCheck
Grab your copy of the tool and hang on tight for the ride!
Configure it
When youโve installed the tool, you can see a new menu option in the "Tools" menu:

Clicking the "SharePoint Dispose Check" menu item will bring up the SPDisposeCheck configuration menu like this:

In this dialog you can configure how the tool should behave, and if it should execute after each build. Whatโs even cooler is you can choose how to treat the problems.
When youโre building your Visual Studio project, the SPDisposeCheck will perform a post-build command (if youโve ticked the Execute After Build checkbox) โ and youโll see the output directly in your Error-window:

False positives
When it comes to checking for dispose problems or leaks with this tool, it can sometimes give you something youโd refer to as "a false positive". What that generally means is that although the tool might report a problem, it really isnโt.
Ignoring reports
Sometimes with the SPDisposeCheck tool youโll get quite a bunch of "false positives" reported, or for whatever other reason youโd like to ignore certain error messages from the SPDisposeCheck tool โ you can do that by implementing the SPDisposeCheckIgnore attribute (available as source code in the SPDisposeCheck installation folder).
The following code snippet is taken from the "SPDisposeCheckIgnoreAttribute.cs" file in the SPDisposeCheck installation folder. Add this code to your project (you can change the namespace..):
using System;
namespace Zimmergren.SP2010.DisposePatterns
{
public enum SPDisposeCheckID
{
// SPDisposeCheckIDs.
SPDisposeCheckID_000 = 0,
SPDisposeCheckID_100 = 100,
SPDisposeCheckID_110 = 110,
SPDisposeCheckID_120 = 120,
SPDisposeCheckID_130 = 130,
SPDisposeCheckID_140 = 140,
SPDisposeCheckID_150 = 150,
SPDisposeCheckID_160 = 160,
SPDisposeCheckID_170 = 170,
SPDisposeCheckID_180 = 180,
SPDisposeCheckID_190 = 190,
SPDisposeCheckID_200 = 200,
SPDisposeCheckID_210 = 210,
SPDisposeCheckID_220 = 220,
SPDisposeCheckID_230 = 230,
SPDisposeCheckID_240 = 240,
SPDisposeCheckID_300 = 300,
SPDisposeCheckID_310 = 310,
SPDisposeCheckID_320 = 320,
SPDisposeCheckID_400 = 400,
SPDisposeCheckID_500 = 500,
SPDisposeCheckID_999 = 999
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Assembly,
Inherited = false, AllowMultiple = true)]
public class SPDisposeCheckIgnore : Attribute
{
public SPDisposeCheckIgnore(SPDisposeCheckID Id, string Reason)
{
_id = Id;
_reason = Reason;
}
protected SPDisposeCheckID _id;
protected string _reason;
public SPDisposeCheckID Id
{
get { return _id; }
set { _id = Id; }
}
public string Reason
{
get { return _reason; }
set { _reason = Reason; }
}
}
}
Once youโve done that, you can use the attribute on your methods and assemblies to tell them to ignore that specific item.
Example usage of the SPDisposeCheckIgnore attribute:
[SPDisposeCheckIgnore(SPDisposeCheckID.SPDisposeCheckID_110, "False Positive, nothing to see here, move along!")]
private static void MyAwesomeMethod()
{
// Your method code with false positives
}
What if Iโm an awesome coder already?
Too many times have I encountered problems in projects due to not properly checking for memory leaks.
Better safe than sorry. Thatโs all Iโm going to say about that :-)
Summary & Links
What weโve learned from this article is that you should always keep in mind how you handle your objects in your code โ and especially when it comes to the SharePoint objects that are invoking unmanaged code like the SPWeb and SPSite objects (to name two common ones).
Make sure youโve downloaded the latest version of the SPDisposeCheck tool to get the aforementioned fancy integration into Visual Studio 2010. Itโs pretty awesome indeed!
Links / Resources
- Logging in SharePoint 2010
- Dispose Patterns
- SPDisposeCheck
- SPDisposeCheck Static Analysis Ruleset
- Must read: Best Practice: Using Disposable Windows SharePoint Services Objects
Enjoy!
Recent comments