You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置MemoryCache的MemoryCacheEntryOptions实现LRU缓存淘汰?

MemoryCache实现LRU缓存策略的问题解答

可以的,Microsoft.Extensions.Caching.Memory.MemoryCache 默认就支持**最近最少使用(LRU)**的缓存淘汰策略,你的现有配置已经满足基础要求,仅需注意几个细节:

核心逻辑说明

当你为MemoryCache设置SizeLimit,且每个缓存条目通过MemoryCacheEntryOptions.SetSize()指定大小后,一旦缓存总大小超过限制,MemoryCache会自动触发LRU淘汰——移除当前最近最少被访问(读取/写入)的条目,无需额外配置其他参数。

你的代码分析

正确配置点

  1. 缓存总容量限制:构造MemoryCache时设置SizeLimit = 5,结合每个条目SetSize(1),意味着缓存最多保留5个条目。
  2. 条目大小设置:SetValue方法中为每个条目指定大小为1,确保缓存能正确计算总占用空间,触发淘汰逻辑。

代码笔误修正

你的类MemoryCacheManagement的构造函数名称写成了MemoryCacheRepository,需要修正为与类名一致:

public class MemoryCacheManagement
{
    private MemoryCache Cache { get; set; }
    
    public MemoryCacheManagement()
    {
        Cache = new MemoryCache(new MemoryCacheOptions
        {
            SizeLimit = 5
        });
    }
    
    public void SetValue<T>(string key, T value)
    {
        Cache.Set(key, value, new MemoryCacheEntryOptions()
            .SetSize(1)
        );
    }

    // 新增Get方法用于验证缓存状态
    public bool TryGetValue<T>(string key, out T value)
    {
        return Cache.TryGetValue(key, out value);
    }
}

测试代码验证

你可以在测试中添加断言,验证LRU逻辑是否生效:

[Test]
public void TestLRUBehavior()
{
    var cache = new MemoryCacheManagement();

    User[] users = new User[]
    {
        new User { Id = 1, Name = "User1", Age = 20 },
        new User { Id = 2, Name = "User2", Age = 21 },
        new User { Id = 3, Name = "User3", Age = 22 },
        new User { Id = 4, Name = "User4", Age = 21 },
        new User { Id = 5, Name = "User5", Age = 22 },
        new User { Id = 6, Name = "User6", Age = 21 },
        new User { Id = 1, Name = "User1", Age = 20 },
        new User { Id = 7, Name = "User7", Age = 22 },
        new User { Id = 2, Name = "User2", Age = 21 },
        new User { Id = 3, Name = "User3", Age = 22 },
        new User { Id = 2, Name = "User2", Age = 21 },
        new User { Id = 3, Name = "User3", Age = 22 }
    };

    foreach (var user in users)
    {
        cache.SetValue(user.Id.ToString(), user);
    }

    // 最终缓存应保留最近频繁访问的条目:1、2、3、6、7
    Assert.IsTrue(cache.TryGetValue<User>("1", out _));
    Assert.IsTrue(cache.TryGetValue<User>("2", out _));
    Assert.IsTrue(cache.TryGetValue<User>("3", out _));
    Assert.IsTrue(cache.TryGetValue<User>("6", out _));
    Assert.IsTrue(cache.TryGetValue<User>("7", out _));
    
    // 验证被LRU淘汰的条目:4、5
    Assert.IsFalse(cache.TryGetValue<User>("4", out _));
    Assert.IsFalse(cache.TryGetValue<User>("5", out _));
}

关键注意事项

  • 任何对缓存条目的读取(Get/TryGetValue)或写入(Set)操作,都会更新条目的"最近使用时间",确保LRU逻辑准确。
  • 如果不设置条目大小,SizeLimit不会生效,缓存不会触发自动淘汰。

内容的提问来源于stack exchange,提问作者Garry A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:45:35