Freigeben über


Tracking down objects not conforming to sharepoint disposal best practices

Background: All SPsite and SPweb objects make use of unmanaged code and needs to be disposed off explicitly in the finally method or by making use of
the 'using' statement. Below is the sample that shows appropriate use of sharepoint object model.

Below is the recommended sample code for above that makes use of Dispose () method
String str;
SPSite oSPSite = null;
SPWeb oSPWeb = null;

try
{
   oSPSite = new SPSite("https://site1");
   oSPWeb = oSPSite.OpenWeb(..);

   str = oSPWeb.Title;
}
catch(Exception e)
{
   //Handle exception, log exception, etc.
}
finally
{
   if (oSPWeb != null)
     oSPWeb.Dispose();

   if (oSPSite != null)
     oSPSite.Dispose();
}

Alternate sample code that shows the use of 'using' keyword

public void UsingBestPractice()
{
    using (SPSite siteCollection = new SPSite("https://site2"))
    {
        using (SPWeb web = siteCollection.OpenWeb())
        {
              //...
        } // SPWeb object web.Dispose() automatically called
    }  // SPSite object siteCollection.Dispose() automatically called
}

Case study : In a recent engagement for capacity planning for sharepoint application, load testing on the system conducted revealed the below messages in the ULS logs.

"Potentially excessive number of SPRequest objects (number of objects) currently unreleased on thread number of thread. Ensure that this object or its parent (such as an SPWeb or SPSite object) is being properly disposed. Allocation Id for this object: {GUID}"

"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: {GUID}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"

The first message appears if the number of SPrequest objects exceed the default value of 8. However, this value can be changed by editing a registry key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings

LocalSPRequestWarnCount = desired threshold value

However, be aware of too many SPrequest objects(>50). You might have to look into redesigning your app if this value gets too high.

In order to look into the issue reported by the second message we need to get a stack trace so as to track the origin of the method which could have potential memory leaks

The registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings
SPRequestStackTrace = 1 was set to do the same and the machine restarted to reflect the settings

The system was then retested to spot the stack trace in the ULS logs. The stack trace function emmited was from the below methods

a)Microsoft.SharePoint.RecordCenterAddOnPack.Common.CustomExpirationFormula.ComputeExpireDate
b) Microsoft.Office.RecordsManagement.RecordsRepository.HoldingZone.CallCustomRouters

In order to confirm that it was indeed an issue, the custom code was taken from which the above stack trace was emmitted. 14 instances of code were found which did not conform to
the sharepoint object disposal best practices as explained in the background section. All of those were related to SPsite and SPweb objects

There is one other way to figure out code that does not confirm to sharepoint best practices. This can be done through the use of a tool called
SPDisposeCheck. See the link https://code.msdn.microsoft.com/SPDisposeCheck for more information.