问题描述
我正在开发 .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 (将#修改为@)