Following the guidance below (1) to ensure that the stack trace of the allocation of the SPRequest object is preserved in memory and added to the ULS logs, I'm seeing a steady stream of 8l1n (High) messages during a full-crawl that seem to pin-point .ParentWebId as the source of the leak.
Recognizing that .ParentWeb (2) clean-up is now handled automatically by the SharePoint framework itself, is there a possibility that .ParentWebId, which has a different implementation (3), is still susceptible, or is the ULS warning slightly misleading in identifying the source?
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: {0B518506-3A73-4E7B-BB14-5CC80267812A}
This SPRequest was allocated at
at Microsoft.SharePoint.Library.SPRequest..ctor()
at Microsoft.SharePoint.SPGlobal.CreateSPRequestAndSetIdentity(Boolean bNotGlobalAdminCode, String strUrl, Boolean bNotAddToContext, Byte[] UserToken, String userName, Boolean bIgnoreTokenTimeout, Boolean bAsAnonymous)
at Microsoft.SharePoint.SPWeb.InitializeSPRequest()
at Microsoft.SharePoint.SPWeb.EnsureSPRequest()
at Microsoft.SharePoint.SPWeb.get_Request()
at Microsoft.SharePoint.SPWeb.EnsureWebAncestry()
at Microsoft.SharePoint.SPWeb.get_ParentWebId()
(1) Troubleshooting SPSite/SPWeb leaks in WSS v3 and MOSS 2007 http://blogs.technet.com/b/stefan_gossner/archive/2008/05/07/troubleshooting-spsite-spweb-leaks-in-wss-v3-and-moss-2007.aspx
(2) Best Practices: Using Disposable Windows SharePoint Services Objects http://msdn.microsoft.com/en-us/library/aa973248.aspx
(3) ParentWebId vs. ParentWeb
public SPWeb ParentWeb
{
get
{
this.InitWeb();
if (!this.m_bParentWebInited)
{
string parentWebUrl = this.Request.GetParentWebUrl(this.Url);
if (parentWebUrl != null)
{
this.m_ParentWeb = this.Site.OpenWeb(parentWebUrl);
}
else
{
this.m_ParentWeb = null;
}
this.m_bParentWebInited = true;
}
return this.m_ParentWeb;
}
}
public Guid ParentWebId
{
get
{
if (this.m_guidParentWebId == Guid.Empty)
{
this.EnsureWebAncestry();
if (this.m_rgAncestors != null)
{
int length = this.m_rgAncestors.GetLength(1);
if (length > 0)
{
object obj2 = this.m_rgAncestors[0, length - 1];
if (obj2 != null)
{
this.m_guidParentWebId = new Guid(obj2.ToString());
}
}
}
}
return this.m_guidParentWebId;
}
}