I’ve been waiting for this for a couple months after an announcement was made that it was going to be released, and finally today the SPDisposeCheck tool has been released! The tool reviews a .NET Assembly (DLL or EXE) and evaluates SharePoint API's used in that assembly. It will produce a report identifying where code doesn't follow best practices for memory management in SharePoint.
To test this out, I created a simple console application that contains undisposed SharePoint objects:
static void Main(string[] args) {
SPSite siteCollection = new SPSite("http://server");
SPWeb site = siteCollection.OpenWeb();
// do something
}
As you know, you must always be sure to dispose of your SPSite and SPWeb objects, as this can lead to expensive memory leaks. If you’re not a seasoned SharePoint developer, this may not be obvious to you, and for this the SPDisposeCheck tool is a huge asset. I ran the following command after downloading the tool:
SPDisposeCheck.exe C:\Projects\Test\Aaron.TestApp\bin\Aaron.TestApp.exe
Which produced the following:
You can see that 2 errors were found. Specifically, this tool points out the following for the first error:
Disposable type not disposed: Microsoft.SharePoint.SPSite
***This may be a false positive depending on how the type was created or if it is disposed outside the current scope
This tells me that my SPSite object needs disposed. The second error is exactly the same thing, except in reference to SPWeb. Let’s clean up the code, this time disposing of our objects:
using (SPSite siteCollection = new SPSite("http://server")) {
using (SPWeb site = siteCollection.OpenWeb()) {
// do something
}
}
Now, when I run this tool I get the following:
There’s a pretty good chance that if you’ve even made it this far in this post, that you’ve written SharePoint code before, and already know to always dispose of your SPSite/SPWeb objects. However, what about the less obvious examples. I ran this tool on an assembly I’m currently developing for a client, and I got an error:
Notes: Dispose/Close was not called on SPLimitedWebPartManager.Web
I went back through my code, and found this line:
SPLimitedWebPartManager manager = defaultPage.GetLimitedWebPartManager(PersonalizationScope.Shared);
Basically this gets the web part manager for a specific page, so you can add/delete/modify the web parts that are on it. Why is this throwing an error? I’m not using an SPSite OR an SPWeb anywhere! It’s because there’s a very non-obvious memory leak in this that creates its own SPWeb object, and this object needs to be disposed. The correct usage of this is:
using (SPLimitedWebPartManager manager =
defaultPage.GetLimitedWebPartManager(PersonalizationScope.Shared)) {
// do something
if (manager.Web != null)
manager.Web.Dispose();
}
Not at all obvious, but I’m glad this tool caught it! PLEASE, if you are writing Object Model code, run this tool. For a ton more information on SharePoint Dispose() patterns, Roger Lamb’s post is by far the best one out there. Also check out this MSDN article.
You can (and really should) download this tool here.