Reputation: 3787
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
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
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