Thorkil Værge
Thorkil Værge

Reputation: 3787

What do the size settings for MemoryCache mean?

In a controller class, I have

using Microsoft.Extensions.Caching.Memory;
private IMemoryCache _cache;
private readonly MemoryCacheEntryOptions CacheEntryOptions = new MemoryCacheEntryOptions()
    .SetSize(1)
    // Keep in cache for this time
    .SetAbsoluteExpiration(TimeSpan.FromSeconds(CacheExpiryInSeconds));

And in Startup.cs, I have

public class MyMemoryCache
    {
        public MemoryCache Cache { get; set; }
        public MyMemoryCache()
        {
            Cache = new MemoryCache(new MemoryCacheOptions
            {
                SizeLimit = 1024,
            });
        }
    }

What do these various size settings mean?

This is .NET Core 2.1.

Upvotes: 39

Views: 26894

Answers (2)

Vahid Farahmandian
Vahid Farahmandian

Reputation: 6568

SizeLimit means what is the total volume? Size or what the SetSize do is to specify what share of the total volume does it require?

For example in following code:

var cache = new MemoryCache(new MemoryCacheOptions
{
    SizeLimit = 3,
});

It is said that the total volume is equal to 3. Based on this total volume, in the following code:

1>> cache.Set("item1", "I am ITEM 1", new MemoryCacheEntryOptions().SetSize(2));
2>> cache.Set("item2", "I am ITEM 2", new MemoryCacheEntryOptions().SetSize(2));
3>> cache.Set("item3", "I am ITEM 3", new MemoryCacheEntryOptions().SetSize(1));

In line 1, we need to store something in cache which it requires 2 of the total available volume of 3. Since the requested volume is available, then the operation is performed. The total available volume now is: 3-2=1

In line 2, again we need to store something in cache which it needs 2 of the total available volume of 1. Since the requested volume is not available, the operation is not performed

In line 3, we need to store something in cache which it needs 1 of the total available volume of 1. Since the requested volume is available, then the operation is performed. The total available volume now is: 1-1=0

Nothing will be cached from here on until some of the total volume is freed again.

So, in the following code:

var cache = new MemoryCache(new MemoryCacheOptions
{
    SizeLimit = 3,
});

cache.Set("item1", "I am ITEM 1", new MemoryCacheEntryOptions().SetSize(2));
cache.Set("item2", "I am ITEM 2", new MemoryCacheEntryOptions().SetSize(2));
cache.Set("item3", "I am ITEM 3", new MemoryCacheEntryOptions().SetSize(1));

var item1 = (string)cache.Get("item1");
var item2 = (string)cache.Get("item2"); //<<! attention
var item3 = (string)cache.Get("item3");

item1 and item3 will contains the cached values, but item2 will be null;

Upvotes: 0

David L
David L

Reputation: 33833

I was able to hunt down some helpful documentation.

SizeLimit does not have units. Cached entries must specify size in whatever units they deem most appropriate if the cache size limit has been set. All users of a cache instance should use the same unit system. An entry will not be cached if the sum of the cached entry sizes exceeds the value specified by SizeLimit. If no cache size limit is set, the cache size set on the entry will be ignored.

It turns out that SizeLimit can function as the limit on the number of entries, not the size of those entries.

A quick sample app showed that with a SizeLimit of 1, the following:

var options = new MemoryCacheEntryOptions().SetSize(1);
cache.Set("test1", "12345", options);
cache.Set("test2", "12345", options);

var test1 = (string)cache.Get("test1");
var test2 = (string)cache.Get("test2");

test2 will be null.

In turn, SetSize() allows you to control exactly how much of your size limit an entry should take. For instance, in the following example:

var cache = new MemoryCache(new MemoryCacheOptions
{
    SizeLimit = 3,
});

var options1 = new MemoryCacheEntryOptions().SetSize(1);
var options2 = new MemoryCacheEntryOptions().SetSize(2);
cache.Set("test1", "12345", options1);
cache.Set("test2", "12345", options2);

var test1 = (string)cache.Get("test1");
var test2 = (string)cache.Get("test2");

both test1 and test2 will have been stored in the cache. But if SizeLimit is set to 2, only the first entry will be successfully stored.

Upvotes: 47

Related Questions