上一节介绍的SPSite和SPWeb对象是开发过程中应用服务器端对象模型操作SharePoint的基础和入口,几乎每一次都会用到它们。这两个对象实现了IDisposable接口(如果对象具有Dispose方法,则意味着实现了IDisposable接口),使用它们时需要注意及时释放,以防止不再使用的对象堆积在内存而造成异常情况。
明确地说,在使用完诸如SPSite、SPWeb这样的对象后,要及时显示地释放她们,而不应依赖垃圾回收器。
如何判定发生了此类异常呢?可以检查ULS日志(位于C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\LOGS目录),看看其中是否有与SPRequest对象相关的条目。SharePoint会监视每个特定线程和并行线程中存在的SPRequest对象的数目,并在以下三种情况下向日志中添加有用的条目:
(1)SPRequest对象的总数超出了可配置的阈值。
(2)SPRequest对象在线程结束后继续存在。
(3)SPRequest对象已通过垃圾收集从堆中移除。
第一种情况是最常发生的,每当SPRequest对象的数目超过网站的阈值时,ULS日志中就会出现以下条目:
●“可能有过量的 SPRequest对象(对象数)当前在线程 线程号 上未得到释放。请确保正确释放此对象或其父项(如SPWeb或SPSite对象)。此对象的分配ID为:{GUID}”
如果想增大网站的阈值,可以通过编辑以下注册表子项来更改此阈值:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings
LocalSPRequestWarnCount = 所需阈值
在确定可能有该内存问题时,可以通过查找以下两条消息来确定错误释放的特定实例:
●在此线程结束之前未释放SPRequest对象。为了避免浪费系统资源,请在用完此对象或其父项(如SPSite或SPWeb)之后立即将其释放。现在将释放此对象。分配 ID: {GUID}。要确定在哪里分配了此对象,请在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings处创建注册表子项。然后在此项下面创建名为SPRequestStackTrace且值为1的新DWORD。
此消息表明SPRequest对象由于在线程结束后仍然存在而被释放。
●SPRequest对象已被垃圾收集器回收,而不是被明确释放。为了避免浪费系统资源,请在用完此对象或其父项(如SPSite或SPWeb)之后立即将其释放。分配 ID: {GUID}。要确定在哪里分配了此对象,请在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings处创建注册表项。然后在此项下面创建名为SPRequestStackTrace且值为1的新DWORD。
此消息表明垃圾收集器释放了SPRequest对象。
确保释放的编码方式有三种:显示调用Dispose方法、使用using语句块和使用try、catch和finally语句块。
显示调用Dispose方法:web.Dispose();
使用using语句块:
using (SPSite site = new SPSite("http://mysiteurl/subsite")) { using (SPWeb web = site.OpenWeb()) { //todo } }
使用try、catch和finally语句块:
SPSite site = null; SPWeb web = null; try { site = new SPSite("http://server"); web = site.OpenWeb(); } catch (Exception e) { //处理发生的异常 } finally { if (web != null) web.Dispose(); if (site != null) site.Dispose(); }
另一方面,对于从上下文(即SPContext)中获取到的对象是不能进行释放的,这个会由SharePoint框架自行管理,如果主动释放会造成异常抛出。这些对象包括:SPContext.Site、 SPContext.Current.Site、SPContext.Web和SPContext.Current.Web等。
开发人员应该从平时多多积累最佳实践的经验,避免写出有潜在威胁的代码。
如果读者有过一些SharePoint的维护或开发经验,就会切身感受到有些SharePoint的异常不是特别好处理,一个问题可能有几种不同的原因导致。因此对于这种可以明确规避的风险,请务必要认真对待,将其克服掉。
下面是关于开发过程中SPSite和SPWeb对象释放方面最佳实践的一些说明。