When starting with SharePoint development, a common question is “Which objects should I dispose?”. This is crucial because SharePoint leaks approximately 1 MB of memory per undisposed IDisposable object. For components like menus, this can quickly add up to 10 MB per page load.

While the MSDN documentation provides comprehensive guidance, here’s the quick answer:

In your WebPart, dispose of all SPWeb and SPSite objects except:

  • SPContext.Current.Site
  • SPContext.Current.Web
  • SPContext.Current.Site.RootWeb

For Features, dispose of all SPWeb and SPSite objects except those provided in your “properties” variable.

Why? SharePoint passes these context objects to multiple components. If you dispose of them prematurely, subsequent components will likely crash. Debugging these issues can be tricky since the crash occurs in a later component, even though the problem originated in an earlier one that incorrectly disposed of a shared context object.

If you’re unsure about disposing an object, it’s better to verify. Here’s a helper method that safely disposes an SPWeb object and its parent hierarchy up to a specified generation, while respecting SharePoint’s context objects:

public static SPWeb GetParentWebAndDispose(SPWeb web, int generations)
{
    if (web == null)
        return null;
        
    for (int i = 0; i < generations; i++)
    {
        SPWeb toDispose = web;
        web = web.ParentWeb;
        
        if (toDispose != null && toDispose != SPContext.Current.Web)
            toDispose.Dispose();
            
        if (web == null)
            break;
    }
    return web;
}