2

I'm hunting memory leaks in an asp.net website. One that I found was that the code wasn't releasing event handlers when controls were no longer needed. I went with the disposing pattern as shown on MSDN to clean them up, and put the calls to remove the event handlers inside the if (disposing) block since they were managed resources, but unless I go through and add destructors to each page and have them all manually dispose the controls nothing fires until the finalizer cleans up the mess. Doing it that way would be brittle and make re-introducing a leak in the future relatively easy; would I be better off ignoring the convention about not touching non-managed objects in code ran by the finalizer?

// Design pattern for a base class.
public class Base: IDisposable
{
   //Implement IDisposable.
   public void Dispose() 
   {
     Dispose(true);
      GC.SuppressFinalize(this); 
   }

   protected virtual void Dispose(bool disposing) 
   {
      if (disposing) 
      {
         myControl.SomeEvent -= SomeEventHandler;
         // Free other state (managed objects).
      }
      // Free your own state (unmanaged objects).
      // Set large fields to null.
   }

   // Use C# destructor syntax for finalization code.
   ~Base()
   {
      // Simply call Dispose(false).
      Dispose (false);
   }
}
CharithJ
  • 46,289
  • 20
  • 116
  • 131
  • You might want to see this question: http://stackoverflow.com/questions/1192554/does-asp-net-call-dispose-on-the-page-controls-in-a-page-or-must-i-do-this/1193226 Some of the answers have some good information that might be helpful to you. – CodingGorilla Oct 14 '11 at 20:36
  • possible duplicate of [Do I need to unsubscribe from (manually subscribed to) events in asp.net?](http://stackoverflow.com/questions/345130/do-i-need-to-unsubscribe-from-manually-subscribed-to-events-in-asp-net) – sll Oct 14 '11 at 20:38
  • @sll Thanks. It appears the information I was referring to (linked in my comment to Royi's answer) was incomplete/incorrect. *sigh* Guess I'll have to look elsewhere for the leak. – Dan Is Fiddling By Firelight Oct 14 '11 at 21:03
  • @sll could you add that as an answer? – Dan Is Fiddling By Firelight Oct 14 '11 at 21:11
  • @Dan Neely : this does not make sense to copy/paste answers/questions, this question should be closed as duplicate or just close/remove it – sll Oct 15 '11 at 08:43

3 Answers3

1

the only time you need to touch it is when you want it to be cleaned NOW

Or if you are going to enter a block which creates a lot of objects.

Otherwise - let the GC decide.

p.s. why don't you use the USING mechanism ?

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • I was going off George Stocker's answer here that events needed to be explicitly released to avoid memory leaks: http://stackoverflow.com/questions/3405557/asp-net-website-memory-usage-quite-high – Dan Is Fiddling By Firelight Oct 14 '11 at 20:57
  • I can't do using because I'm never explicitly creating the controls in C#. The only references to them outside of the file where they're defined are a line in the .aspx file of the form using them: `` and a corresponding line in the forms .designer.cs file. – Dan Is Fiddling By Firelight Oct 14 '11 at 21:01
1

Your objects would only be cleaned up once the garbage collector decides that it is ready to run. Generally, you would only implement a dispose if you needed to clean up non-managed resources (like filehandles etc) or external connections. If you are seeing these resources for a long time and through multiple collections then something is probably holding on to a reference somewhere.

The use of dispose is not wrong from what I see ... its not really getting you anything. You are dropping the reference to the event but the underlying objects are going to remain on the heap until the GC decides to collect them.

jtm001
  • 371
  • 2
  • 3
1

When are asp.net controls disposed

Never, if there is any live reference.

Calling the Dispose method is best practice if you have any Disposable Objects. If you just allow them to go out of scope, they will be added to the finalization queue in the first garbage collection cycle. And will release the memory in the second garbage collection cycle after finalization. Finalization is an unwanted overhead if you can call the Dispose method and SuppressFinalization.

And the other thing is in your code example. Having a Finalize method without having any unmanaged code. If you look at the execution path of the Finalize->Dispose(false) you can notice that it does nothing. Because all the managed objects are handled only if disposing. So, there is no point of adding Finalize method if you don't have any unmanaged objects.

The object will be added to the Finalization Queue and call the Finalize method only if that object doesn't have any live references (in the first GC cylcle). So, it's your duty to un-register necessary events. Otherwise Finalize will never execute as long as there is a reference to that object.

Here is a good reference for you on un-registering event handlers.

Is it necessary to explicitly remove event handlers in C#

Community
  • 1
  • 1
CharithJ
  • 46,289
  • 20
  • 116
  • 131