为什么 .NET Core IMemoryCache 分配比需要更多的内存?

问题描述

我正在开发 .NET Core Web Api 应用程序,最近实现了 IMemoryCache 缓存和 BackgroundService 以每小时刷新一次缓存。缓存过期时间为 2 小时,因此它不应在常规 HTTP 请求期间转到数据库。这是我的缓存类和刷新服务:

public class FooCache : IFooCache
{
    private readonly IMemoryCache _cache;
    private readonly string _key = "Foo";
    private readonly int _durationInHours = 2;
    private static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1,1);

    public FooCache(IMemoryCache cache)
    {
        _cache = cache;
    }

    public bool TryGetFoo(out List<FooOutput> values)
    {
        try
        {
            Semaphore.Wait();
            return _cache.TryGetValue(_key,out values);
        }
        finally
        {
            Semaphore.Release();
        }
    }

    public void SetFoo(List<FooOutput> values)
    {
        try
        {
            Semaphore.Wait();
            _cache.Set(_key,values,DateTimeOffset.Now.AddHours(_durationInHours));
        }
        finally
        {
            Semaphore.Release();
        }
    }
}

public class RefreshFooService : BackgroundService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly IFooCache _fooCache;

    public RefreshFooService(IServiceProvider serviceProvider,IFooCache fooCache)
    {
        _serviceProvider = serviceProvider;
        _fooCache = fooCache;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            using (var scope = _serviceProvider.CreateScope())
            {
                var fooData = scope.ServiceProvider.GetrequiredService<IFooData>();
                var foo = await fooData.GetFoo();
                _fooCache.SetFoo(foo);
            }
            await Task.Delay(3600000,stoppingToken); // Refresh every hour
        }
    }
}

我不知道这个对象应该占用多少内存,但我注意到了这一点:没有缓存和 BackgroundService 应用使用了大约 200MB。第一次刷新后 BackgroundService 需要 2.1GB 内存,第二次刷新后需要 ~3.5GB(有时我看到 4GB)并且在刷新后它会保持在这个水平(假设没有 API 请求到来)。

我知道应用程序将旧对象和新对象存储在内存中,就在此处:

var fooData = scope.ServiceProvider.GetrequiredService<IFooData>();
var foo = await fooData.GetFoo();
_fooCache.SetFoo(foo);

...新数据已经在 foo 对象中,但 _fooCache 仍然有旧数据。

但是,foo 对象被分配到缓存后,GC 不应该介入并释放它的内存吗??特别是几个小时后?我错过了什么?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)