.NET4内存缓存泄漏?

.NET4内存缓存泄漏?,.net,caching,memory,memorycache,.net,Caching,Memory,Memorycache,我正在使用带有Sql依赖项的MemoryCache。 我注意到,当使用MemoryCache.Set()时,如果在集合中重写某个项,则会出现内存泄漏。考虑下面的场景: 键为A的项插入到缓存中,并依赖于表1 使用.Set()重新插入具有相同key=A的新项,并依赖于表2 数据库中的表2已更改 ->Item key=a确实已从缓存中删除,但其内存仍在MemoryCache中声明。只有当数据库中Table1的数据发生更改时,才会释放内存 复制代码: public partial class Form1

我正在使用带有Sql依赖项的MemoryCache。 我注意到,当使用MemoryCache.Set()时,如果在集合中重写某个项,则会出现内存泄漏。考虑下面的场景:

  • 键为A的项插入到缓存中,并依赖于表1
  • 使用.Set()重新插入具有相同key=A的新项,并依赖于表2
  • 数据库中的表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);
        }
    }
    
    公共部分类表单1:表单
    {
    常量字符串cs=@“数据源=。\sqlexpress;初始目录=TestDB;”;
    公共表格1()
    {
    SqlDependency.Start(cs);
    初始化组件();
    }
    MemoryCache memCache=新的MemoryCache(“test1”,新的NameValueCollection{
    {“pollingInterval”,“00:00:03”});
    私有无效按钮2\u单击(对象发送者,事件参数e)
    {
    var dep1=GetDep(“从dbo.Table1中选择ID”);
    var dep2=GetDep(“从dbo.Table2中选择ID”);
    var policy=new CacheItemPolicy();
    policy.SlidingExpiration=新的时间跨度(2,0,0);
    policy.ChangeMonitors.Add(新的SqlChangeMonitor(dep1));
    Set(“a”,GetSB(),policy);
    var policy2=新的CacheItemPolicy();
    policy2.SlidingExpiration=新的时间跨度(2,0,0);
    policy2.ChangeMonitors.Add(新的sqlchangemonitors(dep2));
    Set(“a”,GetSB(),policy2);
    }
    私有对象GetSB()
    {
    StringBuilder sb=新StringBuilder(100000000);
    对于(变量i=0;i”+存在);
    }
    }
    

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

    可能需要很长时间才能回答

    公共覆盖对象删除(字符串键,字符串区域名称=null)

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