I have an application built in ASP.NET MVC 3 that uses SQL CE for storage and EF CTP 5 for data access.
I've deployed this site to a shared host only to find that it is constantly being recycled as it's hitting the 100mb limit they set on their (dedicated) application pools.
The site, when running in release mode uses around 110mb RAM.
I've tried using SQL Server Express rather than CE and this made little difference.
The only significant difference is when I removed EF completely (using a fake repo). This dropped the memory usage between 30mb-40mb. A blank MVC template uses around 20mb so I figured this isn't too bad?
Are there any benchmarks for "standard" ASP.NET MVC applications?
It would be good to know what memory utilisation other EF CTP users are getting as well as some suggestions for memory profiling tools (preferably free ones).
It's worth mentioning how I'm handling the lifetime of the EF ObjectContext. I am using session per request and instantiating the ObjectContext using StructureMap:
For<IDbContext>().HttpContextScoped().Use(ctx => new MyContext("MyConnStringName"));
Many thanks Ben
We did manage to reduce our memory footprint quite significantly. The IIS worker process now sits around 50mb compared to the 100+mb before.
Below are some of the things that helped us:
A note on output caching: When ASP.NET MVC was first released we were able to do donut caching, that is, caching a page APART from a specific region(s). The fact that this is no longer possible makes output caching pretty useless if you have user specific information on the page. For example, we have a login status within the navigation menu of the site. This alone means I can't use Output caching for the page as it would also cache the login status.
Ultimately there is no hard and fast rule on how to optimize an application. The biggest improvement in our application's performance came when we stopped using the ORM for building our associations (for the public facing part of our site) and instead loaded them manually into our viewmodels. We couldn't use EF to eagerly load them as there were too many associations (resulting in a messy UNION query).
An example was our tagging mechanism. Entities like BlogPost and Project can be tagged. Tags and tagable entities have a many-to-many relationship. In our case it was better to retrieve all tags and cache them. We then created a linq projection to cache the association keys for our tagable entities (e.g. ProjectId / TagId). When creating the viewmodel for our page we could then build up the tags for each tagable entity without hitting the database. Again, this was specific to our application but it yielded a massive improvement in performance and in lowering our memory usage.
Some of the resources / tools we used along the way:
Whilst we did make improvements that would take us under the hosting company's (Arvixe) application pool limits, I do feel a sense of duty to advise people who are looking at their Windows Reseller plans, that such restrictions are in place (since Arvixe do not mention this anywhere when advertising the plan). So when something looks too good to be true (unlimited x,y,z), it usually is.
The funny thing is, I think they got their estimate from this URL:
P.S. It's great article to check and see if you're doing anything that the guy is describing. (For example caching your pages)
P.S.S. Just checked our system and it's running at 50 megs currently. We're using MVC 2 and EF CTP 4.