書名: SharePoint 2013 應用開發實戰作者名: 劉中正本章字數: 1518字更新時間: 2021-03-26 18:51:20
2.3 對象的釋放
上一節介紹的SPSite和SPWeb對象是開發過程中應用服務器端對象模型操作SharePoint的基礎和入口,幾乎每一次都會用到它們。這兩個對象實現了IDisposable接口(如果對象具有Dispose方法,則意味著實現了IDisposable接口),使用它們時需要注意及時釋放,以防止不再使用的對象堆積在內存而造成異常情況。
這些異常情況包括:
● SharePoint應用程序池頻繁地進行回收,尤其在使用高峰期。
● 應用程序崩潰。
● IIS工作進程W3WP占用的內存異常大。
● 系統和應用程序性能低下。
明確地說,在使用完諸如SPSite、SPWeb這樣的對象后,要及時顯示地釋放她們,而不應依賴垃圾回收器。
2.3.1 如何應用Dispose
如何判定發生了此類異常呢?可以檢查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等。
2.3.2 部分編碼最佳實踐
開發人員應該從平時多多積累最佳實踐的經驗,避免寫出有潛在威脅的代碼。
如果讀者有過一些SharePoint的維護或開發經驗,就會切身感受到有些SharePoint的異常不是特別好處理,一個問題可能有幾種不同的原因導致。因此對于這種可以明確規避的風險,請務必要認真對待,將其克服掉。
下面是關于開發過程中SPSite和SPWeb對象釋放方面最佳實踐的一些說明。
● SPSiteCollection.Add方法將創建并返回新的SPSite實例,需要釋放。
● SPSiteCollection[]索引運算符會針對每次訪問返回一個新的SPSite實例,需要釋放。
● SPSite.AllWebs.Add方法將創建并返回SPWeb實例,需要釋放。
● SPWebCollection.Add方法將創建并返回SPWeb實例,需要釋放。
● SPSite.AllWebs[]索引運算符會在每次訪問對象后返回一個新的SPWeb實例,需要釋放。
● SPSite對象的OpenWeb方法和SelfServiceCreateSite方法將創建SPWeb對象并將其返回給調用方,需要釋放。
● Microsoft.Office.Server.UserProfiles.PersonalSite返回的SPSite對象,需要釋放。
● SPWeb.Webs屬性將返回SPWebCollection對象。需要釋放此集合中的SPWeb對象。
● SPWeb.Webs.Add方法(或SPWebCollection.Add)會創建并返回新的SPWeb對象,需要釋放。
● SPWeb.Webs[]索引運算符會針對每次訪問返回一個新的SPWeb對象,將會通過調用OpenWeb方法來創建SPWeb,需要釋放。
● 如果開發中僅需要獲取網站的信息,可以避免構建SPWeb對象而是使用SPWebCollection的WebsInfo屬性獲取網站集合中各個網站的信息。
- 零起點學Linux系統管理
- SOA實踐者說
- Haskell Financial Data Modeling and Predictive Analytics
- 嵌入式Linux系統開發:基于Yocto Project
- Windows Server 2012網絡操作系統企業應用案例詳解
- 零基礎學鴻蒙PC:新一代國產操作系統
- Linux系統安全基礎:二進制代碼安全性分析基礎與實踐
- VMware NSX Cookbook
- 計算機系統:基于x86+Linux平臺
- Linux內核設計的藝術:圖解Linux操作系統架構設計與實現原理
- 跟老男孩學Linux運維:Shell編程實戰
- Distributed Computing with Go
- Hands-On GPU Programming with Python and CUDA
- Android應用性能優化最佳實踐
- Raspberry Pi入門指南