Memory Leak in EntityDataSource when controlling lifetime of your ObjectContext
The EntityDataSource is a control you can use on your ASP.NET Pages to connect ASP.NET Controls like the GridView to an ADO.NET Entity Framework Data Source. Its the easiest way to display, add or modify data via the Entity Framework.
ObjectContext Lifetime with the EntityDataSource
The default behavior of EntityDataSource is to create a new ObjectContext for every page request and dispose the context again at the end of the page lifecycle.
The EntityDataSource control also allows you to provide your own ObjectContext by using the ContextCreating and ContextDisposing events. There is a good article on msdn that describes the Object Context Life-Cycle managed by the EntityDataSource.
The described approach works fine. It also allows you to use the ObjectContext across page requests. This can be useful when you don’t have data that changes frequently and if you want to save on lots of short living objects that are created when accessing the same data all over again. A description about that can be found in my recent article about the ADO.NET Entity Framework.
Memory Leak with PropertyChangeEventHandler
I created a simple ASP.NET MVC Sample Application where my page hosts a GridView that is linked with an EntityDataSource. I implemented the event handlers as described in the msdn article and passed an application scope instance of my entity classes to the Context property of the EntityDataSource. The actual ObjectContext is provided by my MVC Controller and put into the ViewData. Here are some code-snippets showing how to use my own ObjectContext and how to disable ObjectContext disposal at the end of the page lifecycle:
protected void EntityDataSource1_ContextCreating(object sender, System.Web.UI.WebControls.EntityDataSourceContextCreatingEventArgs e)
{
e.Context = (System.Data.Objects.ObjectContext)this.ViewData["GridData"];
}
protected void EntityDataSource1_ContextDisposing(object sender, System.Web.UI.WebControls.EntityDataSourceContextDisposingEventArgs e)
{
e.Cancel = true;
}
I ran a simple Visual Studio Load Test against this page – requesting the same page for a couple of minutes with a single user. Monitoring the memory showed me a growing Gen2 Heap.
With the help of several memory snaphots which I took within the same test period, I identified the growing class to be System.ComponentModel.PropertyChangedEventHandler.
Walking the referrer tree of those objects brought me to my EntityObject class (Customers) that I used on the page. The interesting detail here is that I only had 25 Entity Objects (that was my page size of the GridView and during my test I only tested the first grid page). Those 25 Entity Objects however had references to 165.800 event handler objects:
Why so many PropertyChangedEventHandler’s?
It turned out that the EntityDataSource is registering a PropertyChangedEventHandler for every property on the EntityObject. I had 25 objects on a page with 13 properties each. Every page request therefore created 325 event handler objects. As we do not allow the EntityDataSource to dispose the ObjectContext (we set e.Cancel to true in the ContextDisposing event handler) – those EventHandlers were never disposed.
The problem of course is that the EntityDataSource has to remove its event handlers regardless whether the ObjectContext will be disposed or not. I did some research on how to programmatically “encourage” the release – but haven’t yet found anything in the documentation nor by browsing through the ADO.NET EntityFramework code (using Reflector).
Conclusion
Be aware of the side effects when using your own ObjectContext. If you use it over a too long period of time with an EntityDataSource you will run into the described memory leak.








Potential Memory Leak in EntityDataSource when controlling lifetime of your ObjectContext…
Thank you for submitting this cool story – Trackback from DotNetShoutout…
Hello Andreas,
Good catch! We will take a look at what is happening here. Feel free to email me.
Thanks,
Diego Vega
Program Manager, Entity Framework Team
Hi Diego
Glad you are looking into this issue. Would be great if you can let us know when this will be addressed. The readers will then know when it is safe to use this feature. Also feel free to post any workaround – I can also add it to the main blog so that the readers dont have to dig through all our comments
Cheers
Andi
Are you saying that you persist the ObjectContext across page requests? Why?
@Mark
My intenion about this is in the blog post. In a scenario where you have data that only frequently or hardly ever changes you may want to keep the data in memory across page requests in order to minimize roundtrips to the database.
There are definitely other ways to do “caching” like this – but I wanted to see how it works with the Entity Framework and by that I ran into the described problem.
I am interested to hear your opinion about this approach.
I know this post is old, but I just have to comment, because all this makes no sense.
Why would you even try this. First you talk about MVC, which is a stateless approach, as opposed to ASP.NET. Still you want to keep 25 objects in memory, which the database should be able to supply in milliseconds, by keeping the object context alive for long periods, which is IMHO a bad practice in itself, with or without memory leak.
Better detach the objects, then re-attach later when necessary. But what good is MVC, when the first thing you try to do is work around it.