【问题标题】:.net 4 MemoryCache leak?.net 4 MemoryCache 泄漏?
【发布时间】:2012-03-28 09:56:49
【问题描述】:

我将 MemoryCache 与 Sql 依赖项一起使用。 我注意到,当使用 MemoryCache.Set() 时,如果集合中的某个项目被覆盖,则会出现内存泄漏。考虑以下场景:

  1. key=A 的项目被插入到缓存中,并依赖于 Table1
  2. 使用 .Set() 重新插入具有相同 key=a 的新项目,并依赖于 Table2
  3. 数据库中的表 2 已更改。

-> Item key=a 确实从缓存中删除了,但它的内存仍在 MemoryCache 中。仅当数据库中 Table1 的数据发生更改时,才会释放内存。

重现代码:

public partial class Form1 : Form
{
    const string cs = @"Data Source=.\sqlexpress;Initial Catalog=TestDB;";
    public Form1()
    {
        SqlDependency.Start(cs);
        InitializeComponent();
    }

    MemoryCache memCache = new MemoryCache("test1", new NameValueCollection { 
        { "pollingInterval", "00:00:03"}});

    private void button2_Click(object sender, EventArgs e)
    {
        var dep1 = GetDep("SELECT ID FROM dbo.Table1");
        var dep2 = GetDep("SELECT ID FROM dbo.Table2");

        var policy = new CacheItemPolicy();
        policy.SlidingExpiration = new TimeSpan(2, 0, 0);
        policy.ChangeMonitors.Add(new SqlChangeMonitor(dep1));

        memCache.Set("a", GetSB(), policy);

        var policy2 = new CacheItemPolicy();
        policy2.SlidingExpiration = new TimeSpan(2, 0, 0);
        policy2.ChangeMonitors.Add(new SqlChangeMonitor(dep2));

        memCache.Set("a", GetSB(), policy2);
    }

    private object GetSB()
    {
        StringBuilder sb = new StringBuilder(100000000);
        for (var i = 0; i < sb.Capacity; i++)
        {
            sb.Append("1");
        }
        return sb.ToString();
    }

    private static SqlDependency GetDep(string sql)
    {
        SqlConnection con = new SqlConnection(cs);
        var cmd = new SqlCommand(sql, con);
        SqlDependency dep = new SqlDependency(cmd);
        con.Open();
        cmd.ExecuteNonQuery();
        con.Close();
        return dep;
    }

    private void button3_Click(object sender, EventArgs e)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
        MessageBox.Show("Total Memory Usage = " + GC.GetTotalMemory(true).ToString());
    }

    private void button1_Click(object sender, EventArgs e)
    {
        bool exists = memCache.Get("a") != null;
        MessageBox.Show("Value exits -> " + exists);
    }
}

要使用代码,点击 Button2 进行初始化,然后更改 Table2 在数据库中的数据。使用 Button3 查看可用内存。

【问题讨论】:

    标签: .net caching memory memorycache


    【解决方案1】:

    大概过了很久才回复。

    public override object Remove(string key, string regionName = null);

    您应该在插入/替换缓存数据之前删除旧密钥。

    【讨论】:

      猜你喜欢
      • 2011-08-05
      • 2022-06-10
      • 2011-03-22
      • 2011-07-21
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 2022-12-06
      相关资源
      最近更新 更多