title: Asp.Net MemoryCache being evicted for no apparent reason
body: <p>I was testing out a bit the <code>System.Runtime.Caching.MemoryCache</code>, to see how it works. </p>
  
  <p>I created a cache as below:</p>
  
  <pre><code>            NameValueCollection config = new NameValueCollection();
              config.Add("cacheMemoryLimitMegabytes", Convert.ToString(250));
              config.Add("pollingInterval", Convert.ToString("00:00:17"));
              config.Add("physicalMemoryLimitPercentage", Convert.ToString(2));
              _m_memoryCacheToUse = new MemoryCache("MemCache",config);
  </code></pre>
  
  <p>I created a test web page, which basically I can specify an amount of items of roughly 1KB memory size (byte array of 1000) to create in cache.  My machine has 12GB of RAM, and current RAM usage is around 40% which leaves me a lot of memory to play with.  From the above settings, I should be using 250MB of ram, or 2% of my physical memory.  For some reason, when I read the settings (<code>cache.PhysicalMemoryLimit</code>) it shows 3% not 2%.   2% should equal 245MB, while 3% should equal to 368MB.  </p>
  
  <p>First of all, I'm not sure how it works.  Default values are 99% for <code>PhysicalMemoryLimit</code> and the <code>CacheMemoryLimitMegabytes</code> is set at 7.8GB on my PC.  So I decided to override both settings.  I don't know how it works when you set them both, so I tried with similar values.  </p>
  
  <p>I am inserting 50,000 items in cache, as per below:</p>
  
  <pre><code>    void btnGenerateCacheStressTest_Click(object sender, EventArgs e)
      {
          TimeSpan slidingExpiration = new TimeSpan(24, 1, 1, 1);
          DateTimeOffset expirationDate = DateTimeOffset.MaxValue;
          int itemsToGenerate = Convert.ToInt32(txtItemsToGenerate.Text);
          var cache = MemCacheToUseToUse;
  
          Random rnd = new Random();
  
          for (int i = 0; i &lt; itemsToGenerate; i++)
          {
              CacheItemPolicy policy = new CacheItemPolicy();
              policy.Priority = CacheItemPriority.Default;
              policy.RemovedCallback += CacheEntryRemovedCallback;
              policy.SlidingExpiration = slidingExpiration;
              policy.AbsoluteExpiration = expirationDate;
  
              string regionName = null;
              string rndKey = ("stressTest-Data-" + DateTime.Now.Ticks + "-" + i);
  
              byte[] bytesArray = new byte[1000];
              rnd.NextBytes(bytesArray);
  
  
              cache.Add(rndKey, bytesArray, policy, regionName);
          }
  
      }
  </code></pre>
  
  <p>I experimented with both <code>NoSlidingExpiration</code>, and defining a sliding expiration.  50,000 of items should equate to roughly 50 - 70MB I guess adding up some overheads.  That is far less than the 256MB I am allowing for cache.  Yet, after a few seconds, the <code>CacheEntryRemovedCallback</code> gets called and cache goes down to even just 1000 items sometimes.  The <code>RemovedReason</code> is <code>Evicted</code>, which MSDN says is done when (<a href="http://msdn.microsoft.com/en-us/library/system.runtime.caching.cacheentryremovedreason(v=vs.110).aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/system.runtime.caching.cacheentryremovedreason(v=vs.110).aspx</a>)</p>
  
  <p>It shouldn't be approaching such limits. Why are they being evicted?</p>