Tuesday, February 19, 2008

DirectoryEntry Close vs Dispose

While I was reading The .NET Developer's Guide to Directory Services Programming yesterday, I came across this passage called Close or Dispose?

There's a class called DirectoryEntry in the System.DirectoryServices namespace which has both a Close and a Dispose method. As it appears,  you get different behavior depending on which of these two methods you call to free up it's memory.

Now, quoting Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries:

CONSIDER proving method Close(), in addition to the Dispose() method, if close is standard terminology in the area. When doing so, it is important that you make the Close implementation identical to Dispose ...

The authors of  The .NET Developer's Guide to Directory Services Programming recommend that one should always use the Dispose method for releasing a DirectoryEntry object, and this for the following reasons:

  • Dispose() suppresses .NET finalization, Close() does not.
  • Calling Close() on a DirectoryEntry object enables rebinding of this object to a different object (NOT recommended).
  • Using .NET 1.x, calling Dispose() is the only way to prevent significant memory leaks due to bugs in the finalization of a DirectoryEntry object. This causes the underlying COM object never to be released. This is fixed with the released of .NET 2.0.

Needless to say that this is not included with the MSDN documentation. Also a violation of their own guidelines. What as shame!

Bottom line, always call Dispose on a DirectoryEntry object. Also make sure that you release DirectoryEntry objects that you get from properties or methods, like the Parent or SchemaEntry property. These properties return a new instance of DirectoryEntry every time you call them (being picky: they should have been methods instead). So make sure you keep a reference so you only have to call them once.

Till next time.

4 comments:

界王 said...

I just thought of one thing. If I did not call either Close() or Dispose() method after retaining a DirectoryEntry object, would it cause memory problem?

One developer in our team recently developed a class, which has a method returning a DirectoryEntry object to represent a user in ActiveDirectory. It seems not a good design (right?) because we could not expect one using the class would call Dispose() or Close() in its program.

Jan Van Ryswyck said...

Eventually, the GC will call the finalizer and free up the memory. This isn't optimal because the DirectoryEntry object survives the first GC (getting promoted to the generation 1 or 2 in the process) and is only freed up at the next consecutive GC's.

I encourage you to always call the Dispose method if your not using the DirectoryEntry object anymore.

界王 said...

Hi,

Thank you for your prompt feedback.

Our web application recently encounters serious memory problem and I am guessing the improper DirectoryEntry manipulation might be one of the root causes.

Since GC would eventually release the memory, I think there should be something else in our application then.

Thank you!

Jan Van Ryswyck said...

I can highly recommend dotTrace for chasing down those performance/memory issues:

http://www.jetbrains.com/profiler/index.html

If you're into nitty gritty debugging, then you could check out this blog as kind of a last resort:

http://blogs.msdn.com/tess/default.aspx

You will find a couple of posts regarding memory issues and ASP.NET.

Take care.