views:

61

answers:

2

This stems from a recent couple of posts I've made on events and memory management in general. I'm making a new question as I don't think the software I'm using has anything to do with the overall problem and I'm trying to understand a little more about how to properly manage things. This is ASP.NET.

I've been trying to understand the needs for Dispose/Finalize over the past few days and believe that I've got to a stage where I'm pretty happy with when I should/shouldn't implement the Dispose/Finalize. 'If I have members that implement IDisposable, put explicit calls to their dispose in my dispose method' seems to be my understanding. So, now I'm thinking maybe my understanding of object lifetimes and what holds on to what is just wrong!

Rather than come up with some sample code that I think will illustrate my point, I'm going to describe as best I can actual code and see if someone can talk me through it.

So, I have a repository class, in it I have a DataContext that I create when the repository is created. I implement IDisposable, and when my calling object is done, I call Dispose on my repository and explicitly call DataContext.Dispose( ). Now, one of the methods of this class creates and returns a list of objects that's handed back to my front end.

Front End -> Controller -> Repository -> Controller -> Front End.

(Using Redgate Memory Profiler, I take a snapshot of my software when the page is first loaded). My front end creates a controller object on page load and then makes a request to the repository sending back a list of items. When the page is finished loading, I call Dispose on the controller which in turn calls dispose on the context. In my mind, that should mean that my connection is closed and that I have no instances of my controller class. If I then refresh the page, it jumps to two 'Live' instances of the controller class. If I look at the object retention graph, the objects I created in my call to the list are being held onto ultimately by what looks like Linq.

The controller/repository aside, if I create a list of objects somewhere, or I create an object and return it somewhere, am I safe to just assume that .NET will eventually come and clean things up for me or is there a best practice? The 'Live' instances suggest to me that these are still in memory and active objects, the fact that RMP apparently forces GC doesn't mean anything?

+1  A: 

If the objects are no longer rooted, they will eventually get removed from memory altogether, but calling Dispose will not cause the object to be completely removed from memory right away. The Dispose merely allows you to clean up unmanaged resources, and resources that need to be freed up asap.

In other words: your connection should be closed, but there will still be a "disposed" DataContext instance in memory.

You might want to read this article about .NET garbage collection.

Thorarin
Thank-you for the article link. I've found a few articles on Simple-Talk and they've all been really helpful.
Hammerstein
+1  A: 

My answer to your your questions consists of 2 parts:

  1. As an application developer, you would never need to perform GC yourself. That is up to .NET. In the Dispose() method, you would only be required to relinquish or free resources that you have acquired, but not required calling any method to do garbage collection explicitly. If you do, at best, when it's done is undeterministic.

  2. When your controller returns a list to the front end, remember that the front end does not need to know nothing about what your server-side (backend) technology is. It could be C#, Java, PHP, you get the idea. The response the backend returns to the front end is just an HTTP response, and complies to the HTTP protocol. So once the response is framed and returned to the frontend, the controller method goes out of scope, the objects in that scope are up for garbage collected. You won't have to worry about memory leaks in that situation.

Khnle