Skip to content

Regression: Items are not being evicted from MemoryCache in .NET 6 #74676

Open
@RobSiklos

Description

@RobSiklos

Description

This works in .NET Framework, but in .NET 6, I'm seeing an issue where items added to a MemoryCache are not evicted based on the cache memory limit.

Likely related, no matter how much I add to the cache, MemoryCache.GetLastSize() always returns 0 in .NET 6.

Reproduction Steps

Run the code below, and notice that items are never evicted from the cache, and that the result of GetLastSize() is always 0.

using System.Collections.Specialized;
using System.Globalization;
using System.Runtime.Caching;

private static readonly TimeSpan CachePollingInterval = TimeSpan.FromSeconds(1);
private const long CacheMemoryLimitMegabytes = 1024;

void Main()
{
    NameValueCollection cacheConfig = new NameValueCollection();
    cacheConfig.Add("cacheMemoryLimitMegabytes", CacheMemoryLimitMegabytes.ToString(CultureInfo.InvariantCulture));
    cacheConfig.Add("physicalMemoryLimitPercentage", "0");
    cacheConfig.Add("pollingInterval", CachePollingInterval.ToString(@"hh\:mm\:ss", CultureInfo.InvariantCulture));

    using (var cache = new MemoryCache("RobTest", cacheConfig))
    {
        Console.WriteLine($"Memory limit: {cache.CacheMemoryLimit} MB");
        Console.WriteLine($"Polling interval: {cache.PollingInterval}");

        int num = 40; // The number of elements we're going to add to the cache.

        for (int i = 0; i < num; i++)
        {
            // Create an array and initialize it with non-default values so that it actually takes up space in memory.
            var arr = new byte[100_000_000];
            for (int j = 0; j < arr.Length; j++) { arr[j] = 0xF; }

            // Add the item to the cache.
            cache.Add(i.ToString(), arr, DateTimeOffset.Now + TimeSpan.FromMinutes(5));

            Console.WriteLine();
            Console.WriteLine($"Elements in the cache: {cache.GetCount()}");
            Console.WriteLine($"Cache size: {cache.GetLastSize()}%");

            Thread.Sleep(1000);
        }
    }
}


Expected behavior

  1. At some point, elements are evicted from the cache, in consideration of the specified polling interval.
  2. At some point, the result of GetLastSize() is non-zero.

Actual behavior

In .NET 6, items are not evicted from the cache, and the result of GetLastSize() is always zero.

Regression?

Yes, this worked as expected in .NET Framework.

Known Workarounds

No response

Configuration

Running .NET 6.0.8 on Windows 10.0.19044.0 (x64)

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions