7

I see a ton of these warnings in my Sitecore log file, using 8.2 Update 3:

5304 01:57:06 WARN  web[isLanguageFallbackValid] cache is cleared by Sitecore.Caching.Generics.Cache`1+DefaultScavengeStrategy[[Sitecore.Caching.IsLanguageFallbackValidCacheKey, Sitecore.Kernel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]] strategy. Cache running size was 89.9 KB.

They come across sometimes multiple times a second. Does anyone have insight into this and how to quiet up the log file?

  • what version of sitecore do you have? – Vlad Iobagiu Jul 16 '17 at 5:12
11

The DefaultScavengeStrategy is responsible for scavenging (freeing up) memory from your caches when your application is maxing out on its memory resources, as determined by the configured cache size limits. The warning that you are seeing indicates that memory usage was maxing out for the specified cache, based on your configured maximum cache sizes, and so Sitecore decided to use the DefaultScavengeStrategy to free up some memory.

If you want to eliminate this warning from your logs there are two things that you can do:

  1. Disable the size limits of your caches via the Caching.DisableCacheSizeLimits setting. Disabling the caching size limits will actually disable the DefaultScavengeStrategy, entirely (excluding the eviction of expired entries). Only do this if your server has a surplus of RAM and will be able to handle ever-growing caches. This means that entries will only evict when expired, not if the system gets short on memory, which could cause the application to eventually crash if it doesn't have enough resources. However, if your server does have enough RAM then this is usually the best option for performance.
  2. Tune your caches by following the procedure outlined in the the CMS Performance Tuning Guide. This is often a safer, albeit more time-consuming solution than simply disabling the cache size limits, but if you aren't confident that your servers have enough RAM to let the caches get as big as they want then this is the route that you should take. Note that this solution does not guarantee that the warnings will be eliminated from your logs, but rather it does have you allocate as much memory as is necessary to each cache so that the warning can be ignored unless it becomes very frequent. This also means that if you add more memory to your server, that will not boost your application's caching ability without re-tuning or then disabling the cache size limits.

More About Cache Eviction and the DefaultScavengeStrategy

In a recent answer that I posted to a question about CachePriority, I included the following excerpt from Sitecore support, in which they describe the general cache eviction process:

In the current caching implementation, the eviction happens when a new key should be added, but there is not enough space left to add it. When a new entry is added to the cache, the CheckSize method checks if there is enough space. If not, cache entries should be evicted or the whole cache should be cleared.

The Scavenge method performs eviction (or cleanup, if necessary). Note: as a result, the scavenge is not performed in case the cache size limits are disabled.

Following with the above, the flow in the code is as follows:

  1. <setting name="Caching.DisableCacheSizeLimits" value="false" />
  2. New cache key, key, is generated
  3. Cache<T>.Add(key, ...) is called to add the new entry, entry, to the cache with the generated key
  4. Cache<T>.CheckSize(entry) is called to check if the cache can fit the size of the new entry, dataLength, without breaking its maximum size limit
  5. If there is not enough space for the new entry, Cache<T>.Scavenge(dataLength) is called to free up enough space for the new entry to be added.
  6. The Cache<T>.Scavenge(dataLength) method calls the DefaultScavengeStrategy.Scavenge(...) method to execute the scavenging. The idea is that newer entries are more relevant and thus should replace old entries if necessary. The method starts with expired entries and then moves onto random entries.

Source of the Cache<TKey>.CheckSize method:

private bool CheckSize(Cache<TKey>.CacheEntry entry)
{
    if (Settings.Caching.DisableCacheSizeLimits)
    {
        return true;
    }

    long dataLength = entry.DataLength;
    if (dataLength > this.MaxSize)
    {
        return false;
    }
    if (this.RemainingSpace > dataLength)
    {
        return true;
    }

    this.Scavenge(dataLength);
    return true;
}

Source of the Cache<TKey>.Scavenge method:

protected virtual void Scavenge(long required)
{
    if (this.RemainingSpace > required || this.scavengeRunning == 1)
    {
        return;
    }

    bool flag = false;
    try
    {
        flag = Interlocked.CompareExchange(ref this.scavengeRunning, 1, 0) == 0;
        if (!flag)
        {
            return;
        }

        Cache<TKey>.DefaultScavengeStrategy.Instance.Scavenge(this, this.box.Data.Values, required);
    }
    finally
    {
        if (flag)
        {
            this.scavengeRunning = 0;
        }
    }
}

Source of the DefaultScavengeStrategy.Scavenge method:

internal virtual void Scavenge(Cache<TKey> cache, ICollection<Cache<TKey>.CacheEntry> cacheContent, long bytesToFree)
{
    Assert.ArgumentNotNull((object) cache, "cache");
    Assert.ArgumentNotNull((object) cacheContent, "cacheContent");

    bytesToFree = this.AdjustSize(cache, cacheContent, bytesToFree);
    if (this.IsFullCleanupLimitReached(cache, cacheContent, bytesToFree))
    {
        this.ClearCache(cache);
    }
    else
    {
        this.ScavengeObsolete(cache, cacheContent, bytesToFree);

        long leftToScavenge;
        if (this.ShouldStopCleanup(cache, bytesToFree, out leftToScavenge))
        {
            return;
        }

        this.DoCleanup(cache, cacheContent, leftToScavenge);

        if (this.ShouldStopCleanup(cache, bytesToFree, out leftToScavenge))
        {
            return;
        }

        this.ClearCache(cache);
    }
}
  • Even assuming you have plenty of RAM, doesn't Caching.DisableCacheSizeLimits cause performance degradation as the cache gets enormous? – Aren Cambre Jan 5 '18 at 22:47
  • @ArenCambre in theory that statement is incorrect, because the scavenge strategies should free up memory when it is in short supply, enabling the application to take full advantage of the power of the machine that serves it. However, because of a bug in .NET’s MemCache class that MS refuses to fix, the caches don’t respond to short supplies of RAM like they should. As such, your statement is correct in practice and for the foreseeable future. – Zachary Kniebel Feb 18 '18 at 3:37
  • you may be right. I was thinking more of problems with increased access time as in-memory caches get huge. – Aren Cambre Feb 18 '18 at 19:28
8

If you do not want to disable cache size limits (which in our situation can cause memory issues when building large indexes on Azure WebApps), you can use the following Sitecore setting to change the "web[isLanguageFallbackValid]" and "master[isLanguageFallbackValid]" sizes:

<sitecore>
  <settings>
    <setting name="Caching.SmallCacheSize" value="100KB" />
  </settings>
</sitecore>

There are a few more of these "hidden" Sitecore cache settings and you can find them here (the original blog unfortunately no longer exists and has spam now, but thanks goes to a certain Robbert Hock for collecting these).

For reference sake here is the list (updated with newer information from what I could find online and based on a default Sitecore 8.2 installation). Please let me know in the comments if you have any other details on this.

<setting name="Caching.BlobIDCacheSize" value="5MB" />

Determines the size of the cache that stores blob IDs. Specify the value in bytes or append the value with KB, MB or GB. The default value is 5MB in Sitecore 8.2.

<setting name="Caching.DebugEnabled" value="false" />

Gets a value indicating whether to output debug information that can help to identify cache issues. The default value is false.

<setting name="Caching.DefaultItemCacheSize" value="10MB" />

Determines the size of the default item cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 10MB.

<setting name="Caching.DefaultPropertyCacheSize" value="500KB" />

Determines the size of the default property cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 500KB.

<setting name="Caching.DefaultProxyCacheSize" value="2.4MB" />

Determines the size of the default proxy cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 2.4MB in Sitecore 8.2.

The following settings aren’t referenced anymore in Sitecore 7.2:

<setting name="Caching.DefaultTemplateCacheSize" value="5MB" />

Determines the size of the default template cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 5MB.

<setting name="Caching.HugeCacheSize" value="100MB" />

Determines the size of a huge cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 100MB.

<setting name="Caching.LargeCacheSize" value="10MB" />

Determines the size of a large cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 10MB.

<setting name="Caching.MediumCacheSize" value="1MB" />

Determines the size of a medium cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 1MB.

<setting name="Caching.TinyCacheSize" value="10KB" />

Determines the size of a tiny cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 10KB.

<setting name="Caching.VirtualUserStateIDCacheSize" value="1MB" />

Determines the size of the virtual user state ID cache. Specify the value in bytes or append the value with KB, MB or GB. The default value is 1MB.

The following settings aren’t referenced anymore after Sitecore 5.1:

<setting name="Caching.Priority" value="CachePriority.Normal" />

Gets the default cache priority. The default value is CachePriority.Normal. Other values can be: Lowest, Low, Below normal, Normal, Above normal, High, Highest & Never remove

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.