Friday 13 June 2014

SharePoint using Clause memory leak

The using Clause
You can automatically dispose of SharePoint objects that implement the IDisposable interface by using the Microsoft Visual C# using statement.
String str;
using(SPSite oSPsite = new SPSite("http://server"))
{
using(SPWeb oSPWeb = oSPSite.OpenWeb())
{
str = oSPWeb.Title;
str = oSPWeb.Url;
}
}
Taking advantage of using statements can greatly simplify your code. As noted in the C# Reference (using Statement), the common language runtime translates using clauses into try and finally blocks, and any objects that implement the IDisposable interface are disposed for you. In many cases, however, using statements are not advisable, or must be used with some caution and understanding of what the runtime is doing. The following code example shows one case where you would not want the runtime to construct a finally block and dispose objects for you. In this case, SPContext returns an SPWeb object.
// Do not do this. Dispose() is automatically called on SPWeb.
using( SPWeb web = SPControl.GetContextWeb(HttpContext.Current)) { ... }
SPContext objects are managed by the SharePoint framework and should not be explicitly disposed in your code. This is true also for the SPSite and SPWeb objects returned by SPContext.Site, SPContext.Current.Site, SPContext.Web, and SPContext.Current.Web.
You must be cautious and aware of what the runtime is doing whenever you combine SharePoint object model calls on the same line. Leaks arising from this scenario are among the hardest to find.
In the following code example, an SPSite object is instantiated but not disposed, because the runtime ensures disposal of only the SPWeb object returned by OpenWeb.
void CombiningCallsLeak()
{
using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())
{
// ... New SPSite will be leaked.
} // SPWeb object web.Dispose() automatically called.
}
You can fix this problem by nesting one using statement within another.
void CombiningCallsBestPractice()
{
using (SPSite siteCollection = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb web = siteCollection.OpenWeb())
{
//Perform operations on site.
} // SPWeb object web.Dispose() automatically called.
} // SPSite object siteCollection.Dispose() automatically called.
}
http://msdn.microsoft.com/en-us/library/ms778813.aspx#sharepointobjmodel__introduction.