c# - Memory Leak when using DirectorySearcher.FindAll() -


i have long running process needs lot of queries on active directory quite often. purpose have been using system.directoryservices namespace, using directorysearcher , directoryentry classes. have noticed memory leak in application.

it can reproduced code:

while (true) {     using (var de = new directoryentry("ldap://hostname", "user", "pass"))     {         using (var mysearcher = new directorysearcher(de))         {             mysearcher.filter = "(objectclass=domain)";             using (searchresultcollection src = mysearcher.findall())             {             }                      }     } } 

the documentation these classes leak memory if dispose() not called. have tried without dispose well, leaks more memory in case. have tested both framework versions 2.0 , 4.0 has run before? there workarounds?

update: tried running code in appdomain, , didn't seem either.

as strange may be, seems memory leak occurs if don't search results. modifying code in question follows not leak memory:

using (var src = mysearcher.findall()) {    var enumerator = src.getenumerator();    enumerator.movenext(); } 

this seems caused internal searchobject field having lazy initialization , looking @ searchresultcollection reflector :

internal unsafenativemethods.idirectorysearch searchobject {         {         if (this.searchobject == null)         {             this.searchobject = (unsafenativemethods.idirectorysearch) this.rootentry.adsobject;         }         return this.searchobject;     } } 

the dispose not close unmanaged handle unless searchobject initialized.

protected virtual void dispose(bool disposing) {     if (!this.disposed)     {         if (((this.handle != intptr.zero) && (this.searchobject != null)) && disposing)         {             this.searchobject.closesearchhandle(this.handle);             this.handle = intptr.zero;         }     ..    } } 

calling movenext on resultsenumerator calls searchobject on collection making sure disposed well.

public bool movenext() {   ..   int firstrow = this.results.searchobject.getfirstrow(this.results.handle);   .. } 

the leak in application due other unmanaged buffer not being released , test made misleading. issue resolved now.


Comments

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -