views:

629

answers:

5

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?

A: 

I suggest you to take a read on :

If none of these advice works. Take a look at Troubleshooting SPSite/SPWeb leaks in WSS v3 and MOSS 2007.

Edit : You should dispose the SPSite object. Since it will dispose all his SPWeb object automatically.

Pascal Paradis
Thanks. I had read the first two articles--of course I know stuff needs to be disposed--but not the third. My question is not about how to dispose of sharepoint objects, but rather how to find which objects are not being disposed.
Robert S.
I've also read the last link. That suggests editing the registry, which I said is not possible.
Robert S.
Okay. I think in this case Chris O'Brien has a clue on your initial question. He use a special pattern for disposing a Sharepoint object. Might be worth the try.
Pascal Paradis
Okay. Well bugs on production servers are always giving headaches.
Pascal Paradis
I was keenly interested in the "disposing SP objects" topic a while back. Sahil Malik (blah.winsmarts.com) has a good post on it. Also, a while back someone explained how to debug/track down SPRequest leaks, I don't remember who wrote that/or where.
Peter Seale
+2  A: 

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.

webwires
I edited the question to show the try{}finally{} block that disposes of the SPWeb.
Robert S.
I'm glad I came back and caught your edit. I think you're right about `RunWithElevatedPrivileges`. I'm going to change the code when I can and test it. Good catch!
Robert S.
Great site by the way! I'm glad to see you found something to help with your problem.
Pascal Paradis
+1  A: 

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
        }
    });
}
Jason Z
This might be a good hint.
Pascal Paradis
The disposal is in a library function. Response.Redirect isn't being used. But good idea nonetheless.
Robert S.
A: 

I haven't found a solution to this problem yet. Does anyone know why the stacktrace isn't in the SharePoint log after I made the suggested Registry change?

Robert S.
+1  A: 

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

Cheers, Stefan