Question

I hope there's a SharePoint expert here on SO who can help with this.

Here's the problem. My SharePoint logs contain this line, several times:

An SPRequest object was not disposed before the end of this thread. To avoid wasting system resources, dispose of this object or its parent (such as an SPSite or SPWeb) as soon as you are done using it. This object will now be disposed. Allocation Id: {8D090AD2-5D55-42C2-9873-2D5486FE257C} To determine where this object was allocated, create a registry key at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings. Then create a new DWORD named SPRequestStackTrace with the value 1 under this key.

I edited the registry and added the key, but the stacktrace is nowhere to be found. It's not in the SharePoint logs or in the Event Viewer.

I really need to find the source of these SPSite/SPWeb leaks and fix them, but I can't just start editing code that may or may not be the source of the problem. Does anyone have any suggestions?

Was it helpful?

Solution

You need to restart the affected processes (if it is w3wp.exe restart IIS) to catch the registry change.

OTHER TIPS

By far the best location for checking Disposal caveats is:

http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx

In your case OpenWeb() will need to be wrapped in a using. If you are disposing it in your fianlly block then I would suggest showing more code to see if you are calling any other "gotcha" instances. Also, it is unneccessary to dispose of certain SPSite and SPWeb objects if they are obtained from the SPContext class.

If you want to track disposals of the object you could inherit them and override the onload and ondispose methods to log them in a verbose messaging way.

Reading your code suggests that the SPWeb object is declared outside of the RunWithElevatedPriviledges delegate. This may have an effect on the way SharePoint disposes of them. It is generally suggested to do what you need to do to the object inside the delegate.

From the http://msdn.microsoft.com/en-us/library/aa973248.aspx link that was previously mentioned:

Calling Response.Redirect WILL NOT execute the finally block. Therefore, before any redirection or transfer of processing can occur, you must dispose of the objects.

Given your example code, you could still be generating objects that do not get disposed because the Dispose() call is in the finally block.

My suggestion would be to reconfigure your code to the following:

try 
{
    //instantiate the SPSite and SPWeb with elevated privileges:    
    SPSecurity.RunWithElevatedPrivileges(delegate() 
    {
        using (SPSite mySite = new SPSite(url)) 
        {
            using (myWeb = mySite.OpenWeb()) 
            {
                //do stuff here
            }
        }
    });
}

If you have multiple layers of Using statements, you can 'stack' them like this and reduce the amount the code gets indented (similar to the way an if statment executes the next line or block):

try 
{
    //instantiate the SPSite and SPWeb with elevated privileges:    
    SPSecurity.RunWithElevatedPrivileges(delegate() 
    {
        using (SPSite mySite = new SPSite(url)) 
        using (myWeb = mySite.OpenWeb()) 
        {
            //do stuff here
        }
    });
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top