0

I've tracked down a leak to my group enumeration code. I've written a test routine and I'm trying to dispose of everything but still it leaks.

Does anyone see what I'm doing wrong? In my test, I call it 100 times in a row and on my small domain, the memory footprint goes from 32MB to over 150MB.

    private void EnumGroups()
    {
        try
        {
            using (PrincipalContext context = new PrincipalContext(ContextType.Domain, "domainname.com"))
            {

                using (PrincipalSearcher srch = new PrincipalSearcher())
                {
                    srch.QueryFilter = new UserPrincipal(context);

                    // do the search
                    using (PrincipalSearchResult<Principal> results = srch.FindAll())
                    {
                        // enumerate over results
                        foreach (UserPrincipal up in results)
                        {
                            using (PrincipalSearchResult<Principal> groups = up.GetGroups())
                            {
                                foreach (GroupPrincipal gp in groups)
                                    gp.Dispose();
                            }
                            up.Dispose();
                        }
                    }
                }
            }
        }
        catch (Exception exc)
        {
            Trace.WriteLine(exc);
        }
    }
Iunknown
  • 347
  • 1
  • 2
  • 16
  • 2
    "memory-footprint" is a pretty nebulous term. How are you measuring this? – spender May 09 '11 at 16:08
  • 1
    Are you sure this is a memory leak and not just the normal use of the memory? If the process completes and you don't do it again, does the memory usage go down in time? – IAmTimCorey May 09 '11 at 16:10
  • 2
    When you call `.Dispose();` this doesn't evit the object from memory, hence it will still have a footprint. The Garbage Collector needs to run to clear up the memory, which runs basically when it needs to. You could try force the GC to run, but it's typically considered bad practice (see http://stackoverflow.com/questions/233596/best-practice-for-forcing-garbage-collection-in-c) – Jaimal Chohan May 09 '11 at 16:16
  • I'm watching the 'Working Set (Memory)' in Task manager. Adding a GC.Collect at the end of the routine doesn't seem to make a difference. In my test, I'm calling the routine 100 times and after the loop is finished and the program is idle, the footprint settles in at about 98MB. – Iunknown May 09 '11 at 16:26
  • The reason, I noticed this it all was one of my beta sites had a memory footprint on 1.3 GB when the service should never get about say 100MB. – Iunknown May 09 '11 at 16:27
  • Watching the 'Working Set (Memory)' in Task manager will not give an accurate representation of your application's memory usage. Typically, GC will make its own mind up when to run meaning that disposed objects still hang around in memory for a while. A decent memory profiler is far more handy for tracking down memory issues. I like scitech's one. http://memprofiler.com/ – spender May 09 '11 at 16:39
  • same issue, not fixed. any Ideas?? – kain64b Apr 25 '13 at 15:48

1 Answers1

0

Execute GetMembers from another temp domain:

dTaskTemporaryDomain = AppDomain.CreateDomain("BUHLO_POBEDIT_ZLO");
        var currentAssembly = Assembly.GetExecutingAssembly();
        AdsApiHelper = (AdsApiHelper)_adTaskTemporaryDomain.CreateInstanceAndUnwrap(currentAssembly.GetName().FullName, typeof(AdsApiHelper).ToString());
        var members = AdsApiHelper.GetMembers(GroupName);
 AppDomain.Unload(_adTaskTemporaryDomain)

...
[serializeble]
class AdsApiHelper {
  GetMembers(String GroupName){
   .....
   return groupPrincipal.GetMembers().Select(m=>m.SamAccountName);
  }
kain64b
  • 2,258
  • 2
  • 15
  • 27