程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 直接遍歷DirectorySearcher.FindAll()之後的內存洩漏

直接遍歷DirectorySearcher.FindAll()之後的內存洩漏

編輯:C#入門知識

這兩天在寫一個小程序,需要用到遍歷AD域的用戶,並且會定時的去刷,根據習慣簡約的寫法,下面的事情就發生了。
//////////////////////////////////////////////////////////////////////////////////
[csharp] 
 DirectoryEntry ent = new DirectoryEntry(@"LDAP://domainName/OU=xxx,DC=xxx,DC=com", "aduserName", "adPassword");  //綁定到AD指定的OU 
DirectorySearcher adSear = new DirectorySearcher(ent); //創建一個search 
adSear.Filter = "(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(description='')))"; //這是一個過濾條件,可以忽略它 
adSear.SearchScope = SearchScope.Subtree; //強制搜索方式 
foreach (SearchResult resEnt in adSear.FindAll();) //遍歷所有搜索到的結果 

//do something not importent 
}  www.2cto.com
adSear.Dispose(); //銷毀搜索對象 
ent.Dispose(); //銷毀根實體 


////////////////////////////////////////////////////////////////////////////////////
上面 這個是循環體(每次會跑20s左右,我的timer是1分鐘,有設置運行判斷)

表面上看沒有問題,運行了10分鐘以上就可以看到內存從 40左右到了50左右,繼續跑會一直漲,內存洩漏已經毫無疑問了。最先我是懷疑我循環體中間的那些操作問題,把所有的三方類全不干掉,最後發現就這點代碼還是會洩漏;聲明了兩個(ent,adSearch)也銷毀了兩個,怎麼就內存洩漏了呢?
查看了N多資料,也考慮到非托管內存的   GC.Collect();加上也沒有效果... 我甚至在msdn去看了 dispose、finalize,但是也沒有結果。後來當我留意到MSDN上面關於DirectorySearcher.FindAll Method的一個remarks:【Due to implementation restrictions, the SearchResultCollection class cannot release all of its unmanaged resources when it is garbage collected. To prevent a memory leak, you must call the Dispose method when the SearchResultCollection object is no longer needed.】,我視乎明白了。
在我的代碼中,沒有明確的聲明searchResultCollection,但是 adSear.FindAll() 他豁然存在,代碼中沒有任何針對它的垃圾回收,於是

 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
[csharp]
.................................... 
SearchResultCollection resRCs = adSear.FindAll(); 
foreach (SearchResult resEnt in resRCs) 
............................ 
resRCs.Dispose(); 


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
{PS:這裡其實也可以直接用 adSear.FindAll().Dispose();}
然後再測試,沒有內存洩漏了
這麼一點事情,花了我大半天的時間來折騰,把中間無數的代碼注釋、測試,刪除....
到這裡我發現,很多習慣的寫法並不一定是好事,包括很多專業的程序員也可能犯錯。而且這些錯誤要在特定的環境才能體現出來,比如我這個,如果搜索的區域小,執行的次數不是很多,你根本感覺不到內存的洩漏。
留在這裡做個備忘吧。。。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved