asp.net caching limit?

15,426

Solution 1

There is a way to upgrade the limit but I would strongly recommend that you use other kind of Caching System (more about this below).

.NET Cache

To know more about the .NET Caching limitation, please read this great answer from a Microsoft .NET Team member.

If you want to see the current limits of .NET Cache, you can try:

var r = new Dictionary<string, string>();

using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache % Machine Memory Limit Used", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_MachineMemoryUsed", String.Concat(pc.NextValue().ToString("N1"), "%"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache % Process Memory Limit Used", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_ProcessMemoryUsed", String.Concat(pc.NextValue().ToString("N1"), "%"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache API Entries", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_Entries", pc.NextValue().ToString("N0"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache API Misses", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_Misses", pc.NextValue().ToString("N0"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache API Hit Ratio", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_HitRatio", String.Concat(pc.NextValue().ToString("N1"), "%"));
}
using (var pc = new PerformanceCounter("ASP.NET Applications", "Cache API Trims", true))
{
    pc.InstanceName = "__Total__";
    r.Add("Total_Trims", pc.NextValue().ToString());
}

MemCached

I'm currently using Memcached, and if you're hosting your site somewhere, you can use a paid service like:

Or, if you're using your own server, you can download Couchbase Community Edition and hosted our own.

You will find more questions here about the use of MemCache, such as:

Make room for any Cache system

To use other cache system without changing your code, you could adopt to create an interface, like

public interface ICacheService
{
    T Get<T>(string cacheID, Func<T> getItemCallback) where T : class;
    void Clear();
}

then is you're using .NET Cache, your implementation would be something like

public class InMemoryCache : ICacheService
{
    private int minutes = 15;

    public T Get<T>(string cacheID, Func<T> getItemCallback) where T : class
    {
        T item = HttpRuntime.Cache.Get(cacheID) as T;
        if (item == null)
        {
            item = getItemCallback();
            HttpRuntime.Cache.Insert(
                cacheID,
                item,
                null,
                DateTime.Now.AddMinutes(minutes),
                System.Web.Caching.Cache.NoSlidingExpiration);
        }
        return item;
    }

    public void Clear()
    {
        IDictionaryEnumerator enumerator = HttpRuntime.Cache.GetEnumerator();

        while (enumerator.MoveNext())
            HttpRuntime.Cache.Remove(enumerator.Key.ToString());
    }
}

and you would use it as:

string cacheId = string.Concat("myinfo-", customer_id);
MyInfo model = cacheProvider.Get<MyInfo>(cacheId, () =>
{
    MyInfo info = db.GetMyStuff(customer_id);
    return info;
});

if you're using Memcached, all you need to do is create a new class that implement ICacheService and select the class you want, either by using IoC or direct call as:

private ICacheService cacheProvider;

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
    if (cacheProvider == null) cacheProvider = new InMemoryCache();

    base.Initialize(requestContext);
}

Solution 2

The cache uses the memory allocation for the worker process. By default the worker process is allowed to get 60 percent of the machine memory in order to do its work .

As per the link, this can be changed to allow more of the machine memory to be used by the worker process by editing the machine.config file. Presumably you have the cache built to already update when it detects that data is out of date, so this should allow you to put more objects into cache.

Solution 3

When inserting an item into the cache add an CacheItemRemovedCallback method.

In the callback log the reason why the item was removed. This way you see if it memory pressure or something else.

public static void OnRemove(string key, 
   object cacheItem, 
   System.Web.Caching.CacheItemRemovedReason reason)
   {
      AppendLog("The cached value with key '" + key + 
            "' was removed from the cache.  Reason: " + 
            reason.ToString()); 
}

http://msdn.microsoft.com/en-us/library/aa478965.aspx

Share:
15,426
dhardy
Author by

dhardy

Updated on July 29, 2022

Comments

  • dhardy
    dhardy almost 2 years

    Possible Duplicate:
    ASP.NET cache maximum size

    I'm caching quite a lot of datatables using asp.net caching (the floowing code):

    HttpContext.Current.Cache.Insert(GlobalVars.Current.applicationID + "_" + cacheName, itemToCache, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(240));
    

    However I think that the cache on the server is getting full and having to re-obtain the datatable data from the database. Is there any limit to the amount of data that can be cached on the server or any IIS settings that can be tweaked?