I’m running a ASP.NET application on Win2003 32bit that tends to allocate a lot of memory. To avoid OutOfMemoryExceptions that start to appear when the W3P process exceeds 1 GB, I have set a maximum virtual memory limit of 850 MB for the this application pool, so the application will restart instead of throwing exceptions.
While not throwing exceptions, these restarts still lead to temporal performance degeneration (low cache hit ratio, aspx compiling etc.), so I’d like to minimize the number of restarts. Watching the performance counters I can see that the ASP.NET cache works as designed (item count and cache hit ratio increasing after start, after I while some items get removed probably due to expiration dates), except for cache trimmings.
E. g. I would expect cache trimming to kick in when e. g. 750 MB are in use and half of that is cache. But it never happens, under load it continues to allocate more and more memory instead of e. g. trashing low prio cache items, until it hits the memory limit.
Does anybody know what would actually trigger cache trimming? Available physical memory? Is there any other setting available to optimize this scenario?
(Yes, I know, 32 bit is so 2004 and with x64 this problem would go away, probably even with the same amount of memory, but for this app I’m stuck with this server for another few months and have to keep it up running...)
I finally found the issue. There is an optional web.config configuration section for the ASP.NET cache: https://msdn.microsoft.com/en-us/library/ms164606(v=vs.100).aspx
The default configuration is absolutely nonsense for 32-bit boxes with more than 2 GB of RAM: it would start to throw out items of the cache, if less than 10% of physical RAM is available. Having e. g. 4 GB of RAM installed and a 2 GB limit per process, this is never going to happen. So the cache size (and therefore heap size, mostly generation 2 heap) is increasing and increasing until you run into OutOfMemoryExceptions, or you reach your app pool limit.
Now I added this to my web.config:
Additionally, I have set the following limits for the application pool:
See this great article for background on these values: http://msdn.microsoft.com/en-us/library/ms972959#monitor_perf_topic10
Now, if I load test my application in a way that a lot of objects will be added to the cache in short time, I can see the ASP.NET cache trims performance counter going up, and memory usage constantly stays under my restart limits.