It rained 22 days in June (in Boston). The last few days were glorious. And I missed the sun while dealing with a memory leak.
We hit this problem while translating legacy Exchange DNs into SMTP addresses in our Exchange Room analysis tool. The culprit -- System.DirectorServices (.Net 3.5)
calls to GetDirectoryEntry().Properties. With each call to System.Directoryservices, memory use jumped by 120 bytes. The annoyance became a problem after we looked up three fields - for 8,000 users.
Microsoft's MSDN Reference says: "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.".
I did that. So did other folks posted similar problems in the MS forums. All were told to use dispose. It didn't work. After reading dozens of responses, someone said try the "using" contruct along with "dispose". I did. It worked.
For those of you who don't want to find the mines by stomping on the ground, here is sample code that shows System.DirectoryServices calls broken out into an excessive number of using blocks:
'return ONE value from AD given a filter
Public Function GetADField(byval strFilter as string, _
byval strField as string) As String
GetADField = ""
Using dsDir As System.DirectoryServices.ActiveDirectory.Domain = _
System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain
Using dsRoot As New DirectoryEntry(dsDir.Name)
Using dsSearcher As New DirectoryServices.DirectorySearcher
dsSearcher.SearchRoot = dsRoot
dsSearcher.Filter = strFilter
dsSearcher.SearchScope = SearchScope.Subtree
dsSearcher.PropertiesToLoad.AddRange(New String() {strField})
dsSearcher.FindAll() 'results
Using dsResult As DirectoryServices.SearchResultCollection = _
dsSearcher.FindAll() 'results
Dim result As DirectoryServices.SearchResult
For Each result In dsResult
Using de As DirectoryEntry = result.GetDirectoryEntry()
GetADField = de.Properties("mail").Value.ToString
de.Dispose()
End Using 'de
Next 'result
dsResult.Dispose()
result = Nothing
End Using 'dsResult
dsSearcher.Dispose()
End Using 'dsSearcher
dsRoot.Close()
dsRoot.Dispose()
End Using 'dsRoot
dsDir.Dispose()
End Using 'dsDir
Return GetADField
End Function
-Russ
Monday, July 13, 2009
Subscribe to:
Post Comments (Atom)
1 comment:
Excellent ! This resolved my problem !!
Post a Comment