首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.net 4 MemoryCache泄漏?

.net 4 MemoryCache泄漏?
EN

Stack Overflow用户
提问于 2012-03-28 09:56:49
回答 1查看 1.4K关注 0票数 3

我在中使用MemoryCache。我注意到,当使用MemoryCache.Set()时,如果集合中的项被覆盖,就会出现内存泄漏。考虑以下情况:

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

->项key=a确实已从缓存中删除,但它的内存仍在MemoryCache中声明。只有当Table1的数据在数据库中发生变化时,才会释放内存。

复制代码:

代码语言:javascript
复制
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进行初始化,然后更改表2在数据库中的数据。使用Button3查看可用内存。

EN

回答 1

Stack Overflow用户

发布于 2018-07-06 18:39:02

很可能过了很长一段时间才会回复。

公共覆盖对象删除(字符串键,字符串regionName = null);

在插入/替换缓存的数据之前,应该删除旧键。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9905128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档