9

I have a relatively large Entity Framework model (approx ~300 tables) for which I pre-generate views to improve query/application performance.

When the application is under minimal load I experience gradually increasing memory consumption within the application over the course of 6-7 hours. Upon reaching approx. 4GB, the application pool is reset and the process repeats.

enter image description here

Figure 1: Showing application memory consumption over the course of 8-9 hours

This application uses a variation of the repository pattern and ensures that instances of my ObjectContext re instantiated and destroyed in the shortest time feasable for each transaction. I also implement IDisposable on all repositories/interfaces in order to clean up any resources.

I have carried out extensive tests on the application with memory profilers such as Red Gate's ANTS profile, WinDbg and others and have so far been unable to determine the exact cause of the memory issue, however have noted the below:

A Red Gate ANTS profiler test shows that there are too many Entity Framework MetadataWorkspaces being created, causing lots of extra object mappings and associated SQL command text to be held. There’s also single instance of myEntities in a particular repository which contains a MetadataWorkspace and the InitializerMetadata cache contains 351 entries at the end of a stress test. These 351 entries each have another copy of myEntities, each of those has a MetadataWorkspace, and each of those has hundreds of object mappings.

My core solution is structured as follows:

  • Presentation - ASP.NET MVC 3
  • Business - Objects, ViewModels, Interfaces
  • Infrastructure - Entity Framework Model
  • Data Access - ADO.NET Direct Data Access

If anybody is able to provide any pointers, I'd be very grateful.

6
  • 5
    I'm not too sure, without having a good look at the code but normally when you are dealing with memory leaks and EF its symptomatic of snapshot tracking not being correctly cleared. You said that you are disposing your context regularly but i would start by double checking that. heres my diagnosis sheet for EF perf problems: blog.staticvoid.co.nz/2012/8/1/… Commented Aug 16, 2013 at 7:40
  • Hi Luke. That's a great resource - thanks for that. I already do most of that (minus the disabling of lazy-loading) and wondered if there was any other specific info I could provide to help get answers to my question? Commented Aug 16, 2013 at 10:47
  • Not quite sure I understand your comment about the ANTS profiler test. Anyway, I would try refactoring that repository. When myEntities refers to itself, you'll end up with memory issues for sure, unless you break the chain with a virtual keyword in the child entries. Commented Apr 17, 2014 at 22:05
  • 3
    Nick, are you using one object context per request? Commented Sep 9, 2014 at 19:26
  • So.. what is the problem? Are you running into performance problems or you just want to fight a memory battle against a memory-managed CLR? Also... When I read that you are implementing IDisposable, my eyebrow raises. Commented Oct 29, 2014 at 17:36

2 Answers 2

4

We are automatically assuming that the problem is the EF. Can be, can be not. There are a lots of points that we should take care, not only data access infrastructure.

With data access issued, as you are using only EF, you can gain fast improvement using simple .AsNoTracking() method. Adopt a ServiceLocator to help you manage your contexts pool.

You can also user Dapper, instead of EF, in ReadOnly situations.

And for last, but not least, use pure ADO.NET, for the more complex queries and a fastest execution.

Refactor your ActionFilters to avoid using some "BaseController" that all controllers inherits is a good practice either.

Check if your IDisposable classes are truly being supressed by CG, adopting the .Dispose(bool) pattern.

Be sure that you are not persisting cache variables for eternity, that will only be released by application pool recycle.

That are just tips, but the hard work will be with you, that have code access. :)

Good luck!

Sign up to request clarification or add additional context in comments.

Comments

0

Check if you have proxy entities stored in session. In the other hand it's not required to call explicitly Dispose() in DbContext. Check this http://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext.html#.U6WdzrGEeTw

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.