SP 2010: Developing for performance Part 5 - Disposal patterns and tools

Tobias Zimmergren
Tobias Zimmergren
💡TIP: Check out the guidance for building sustainable Azure workloads! 🌿

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.

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"?

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.

Zimmergren Sample Memory Consumption Chart

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:

image

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

image

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:

image

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 :-)

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!

Enjoy!

SharePointDevelopment

Tobias Zimmergren Twitter

Hi, I'm Tobias! 👋 I write about Microsoft Azure, security, cybersecurity, compliance, cloud architecture, Microsoft 365, and general tech!

Reactions and mentions


Hi, I'm Tobias 👋

Tobias Zimmergren profile picture

Find out more about me.

Recent comments

Mastodon