Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent many different MVC URLs from filling ASP.NET Cache

Our website uses ASP.NET MVC for a part of the pages in it. These URLs typically have the form http://oursite/detail.mvc/12345/pictures/ In this URL, the 12345 is an ID in the database. We have several hundred thousands objects for which we show detail pages. Recently we noticed a rise in the memory use for the site, so I investigated a bit. We made a memory dump of the production site and found that a significant amount of the total memory use was cause by strings in Cache of the form "dmachine/webroot/1/site/detail.mvc/12345/pictures/" and "H:\site\detail.mvc\12345\pictures\".

Further investigation and heavy use of Reflector has showed that these strings are stored in the ASP.NET Cache in the form of a System.Web.CachedPathData object. This is created by ConfigurationManager when it reads information from the web.config file. It calls HttpContext.GetSection() --> HttpContext.GetConfigurationPathData() --> CachedPathData.GetVirtualPathData(). Eventually, in CachedPathData.GetConfigPathData, the virtual path is determined for the requested path and this is cached in the ASP.NET Cache without expiration.

Now the trouble is that we have millions of different URLs, and for each path the Configuration system stores a number of strings (configPath, virtual path, physical path) in cache. Over time, this information consumes several hundreds of MB, allmost all of the data in cache.

I assume that when memory gets scarce, these entries will be removed, but in operations they don't trust processes that grow and grow. It also seems very inefficient. Is there a way to tell the HttpContext not to cache this information for each unique URL? Or maybe we can map the request path to a simpler URL first and have that used to select the correct web.config?

like image 829
Teun D Avatar asked Sep 14 '09 14:09

Teun D


1 Answers

Well I thought it over (Teun and I work at the same company), and we have two options as far as I can tell:

  1. Do nothing. This article contains a comment from one asp.net team guy, and it shows a couple of ways to prevent the cache from growing and growing: http://forums.asp.net/p/985551/3297967.aspx#3297967, yet doesn't solve the problem of writing a cache entry for each possible route but guarantees that the cache won't throw some out of memory exception.

  2. Solve the problem with a workaround, use querystring parameters instead of fixed routes (/controller.mvc?action=X&params=Y instead of controller.mvc/action/params). This way only controller.mvc gets cached.

After all, I don't think this really is a problem.

like image 154
Jan Jongboom Avatar answered Oct 13 '22 11:10

Jan Jongboom