javascript

java

python

c#

node.js

reactjs

android

php

c++

html

jquery

ruby-on-rails

css

git

ios

.net

sql

c

string

<img src="//i.stack.imgur.com/bk9VA.png" alt="" class="sponsor-tag-img" width="18" height="16"/>android

c# - MemoryCache在配置中不遵守内存限制

我正在使用应用程序中的.NET 4.0 MemoryCache类并尝试限制最大缓存大小,但在我的测试中,似乎缓存实际上并未遵守限制。

我使用的设置,根据MSDN,应该限制缓存大小:

  1. CacheMemoryLimitMegabytes:对象实例可以增长到的最大内存大小(以兆字节为单位)。“
  2. PhysicalMemoryLimitPercentage:“缓存可以使用的物理内存百分比,表示为1到100之间的整数值。默认值为零,表示MemoryCache实例根据计算机上安装的内存量管理自己的内存1“。 1.这不完全正确 - 忽略任何低于4的值并替换为4。

我理解这些值是近似值而不是硬限制,因为清除缓存的线程每隔x秒触发一次,并且还取决于轮询间隔和其他未记录的变量。 然而,即使考虑到这些差异,在将测试应用程序中的CacheMemoryLimitMegabytes和PhysicalMemoryLimitPercentage一起或单独设置后,当第一项从缓存中逐出时,我看到了非常不一致的缓存大小。 为了确保我每次测试10次并计算出平均值。

这些是在具有3GB RAM的32位Windows 7 PC上测试以下示例代码的结果。 在每次测试第一次调用CacheItemRemoved()之后获取缓存的大小。 (我知道缓存的实际大小将大于此)

MemLimitMB    MemLimitPct     AVG Cache MB on first expiry    
   1            NA              84
   2            NA              84
   3            NA              84
   6            NA              84
  NA             1              84
  NA             4              84
  NA            10              84
  10            20              81
  10            30              81
  10            39              82
  10            40              79
  10            49              146
  10            50              152
  10            60              212
  10            70              332
  10            80              429
  10           100              535
 100            39              81
 500            39              79
 900            39              83
1900            39              84
 900            41              81
 900            46              84

 900            49              1.8 GB approx. in task manager no mem errros
 200            49              156
 100            49              153
2000            60              214
   5            60              78
   6            60              76
   7           100              82
  10           100              541

这是测试应用程序:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
namespace FinalCacheTest
{       
    internal class Cache
    {
        private Object Statlock = new object();
        private int ItemCount;
        private long size;
        private MemoryCache MemCache;
        private CacheItemPolicy CIPOL = new CacheItemPolicy();

        public Cache(long CacheSize)
        {
            CIPOL.RemovedCallback = new CacheEntryRemovedCallback(CacheItemRemoved);
            NameValueCollection CacheSettings = new NameValueCollection(3);
            CacheSettings.Add("CacheMemoryLimitMegabytes", Convert.ToString(CacheSize)); 
            CacheSettings.Add("physicalMemoryLimitPercentage", Convert.ToString(49));  //set % here
            CacheSettings.Add("pollingInterval", Convert.ToString("00:00:10"));
            MemCache = new MemoryCache("TestCache", CacheSettings);
        }

        public void AddItem(string Name, string Value)
        {
            CacheItem CI = new CacheItem(Name, Value);
            MemCache.Add(CI, CIPOL);

            lock (Statlock)
            {
                ItemCount++;
                size = size + (Name.Length + Value.Length * 2);
            }

        }

        public void CacheItemRemoved(CacheEntryRemovedArguments Args)
        {
            Console.WriteLine("Cache contains {0} items. Size is {1} bytes", ItemCount, size);

            lock (Statlock)
            {
                ItemCount--;
                size = size - 108;
            }

            Console.ReadKey();
        }
    }
}

namespace FinalCacheTest
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            int MaxAdds = 5000000;
            Cache MyCache = new Cache(1); // set CacheMemoryLimitMegabytes

            for (int i = 0; i < MaxAdds; i++)
            {
                MyCache.AddItem(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
            }

            Console.WriteLine("Finished Adding Items to Cache");
        }
    }
}

为什么MemoryCache不遵守配置的内存限制?

trans by 2019-09-16T22:13:59Z

c# - 如何清除MemoryCache?

我使用MemoryCache类创建了一个缓存。 我添加了一些项目,但是当我需要重新加载缓存时,我想首先清除它。 最快的方法是什么? 我应该遍历所有项目并一次删除一个项目还是有更好的方法?

trans by 2019-09-11T17:13:58Z

.net - MemoryCache.Add和MemoryCache.Set有什么区别?

我阅读了MSDN文档但没有真正理解它。

我相信Set的行为是“替换现有的,或添加”(原子地)。

那是对的吗?

trans by 2019-09-11T11:30:34Z

c# - 正确使用.NET MemoryCach的锁定模式

我假设此代码存在并发问题:

const string CacheKey = "CacheKey";
static string GetCachedData()
{
    string expensiveString =null;
    if (MemoryCache.Default.Contains(CacheKey))
    {
        expensiveString = MemoryCache.Default[CacheKey] as string;
    }
    else
    {
        CacheItemPolicy cip = new CacheItemPolicy()
        {
            AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(20))
        };
        expensiveString = SomeHeavyAndExpensiveCalculation();
        MemoryCache.Default.Set(CacheKey, expensiveString, cip);
    }
    return expensiveString;
}

并发问题的原因是多个线程可以获取空键,然后尝试将数据插入缓存。

什么是最简洁,最干净的方法来使这个代码并发证明? 我喜欢在缓存相关代码中遵循一个好的模式。 链接到在线文章将是一个很大的帮助。

更新:

我根据@Scott Chamberlain的回答提出了这个代码。 任何人都可以找到任何性能或并发问题吗?如果这样做,它将节省许多代码和错误。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Caching;

namespace CachePoc
{
    class Program
    {
        static object everoneUseThisLockObject4CacheXYZ = new object();
        const string CacheXYZ = "CacheXYZ";
        static object everoneUseThisLockObject4CacheABC = new object();
        const string CacheABC = "CacheABC";

        static void Main(string[] args)
        {
            string xyzData = MemoryCacheHelper.GetCachedData<string>(CacheXYZ, everoneUseThisLockObject4CacheXYZ, 20, SomeHeavyAndExpensiveXYZCalculation);
            string abcData = MemoryCacheHelper.GetCachedData<string>(CacheABC, everoneUseThisLockObject4CacheXYZ, 20, SomeHeavyAndExpensiveXYZCalculation);
        }

        private static string SomeHeavyAndExpensiveXYZCalculation() {return "Expensive";}
        private static string SomeHeavyAndExpensiveABCCalculation() {return "Expensive";}

        public static class MemoryCacheHelper
        {
            public static T GetCachedData<T>(string cacheKey, object cacheLock, int cacheTimePolicyMinutes, Func<T> GetData)
                where T : class
            {
                //Returns null if the string does not exist, prevents a race condition where the cache invalidates between the contains check and the retreival.
                T cachedData = MemoryCache.Default.Get(cacheKey, null) as T;

                if (cachedData != null)
                {
                    return cachedData;
                }

                lock (cacheLock)
                {
                    //Check to see if anyone wrote to the cache while we where waiting our turn to write the new value.
                    cachedData = MemoryCache.Default.Get(cacheKey, null) as T;

                    if (cachedData != null)
                    {
                        return cachedData;
                    }

                    //The value still did not exist so we now write it in to the cache.
                    CacheItemPolicy cip = new CacheItemPolicy()
                    {
                        AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(cacheTimePolicyMinutes))
                    };
                    cachedData = GetData();
                    MemoryCache.Default.Set(cacheKey, cachedData, cip);
                    return cachedData;
                }
            }
        }
    }
}
trans by 2019-07-31T16:42:33Z

c# - MemoryCache在配置中不遵守内存限制

我正在使用应用程序中的.NET 4.0 MemoryCache类并尝试限制最大缓存大小,但在我的测试中,似乎缓存实际上并未遵守限制。

我使用的设置,根据MSDN,应该限制缓存大小:

  1. CacheMemoryLimitMegabytes:对象实例可以增长到的最大内存大小(以兆字节为单位)。“
  2. PhysicalMemoryLimitPercentage:“缓存可以使用的物理内存百分比,表示为1到100之间的整数值。默认值为零,表示MemoryCache实例根据计算机上安装的内存量管理自己的内存1“。 1.这不完全正确 - 忽略任何低于4的值并替换为4。

我理解这些值是近似值而不是硬限制,因为清除缓存的线程每隔x秒触发一次,并且还取决于轮询间隔和其他未记录的变量。 然而,即使考虑到这些差异,在将测试应用程序中的CacheMemoryLimitMegabytes和PhysicalMemoryLimitPercentage一起或单独设置后,当第一项从缓存中逐出时,我看到了非常不一致的缓存大小。 为了确保我每次测试10次并计算出平均值。

这些是在具有3GB RAM的32位Windows 7 PC上测试以下示例代码的结果。 在每次测试第一次调用CacheItemRemoved()之后获取缓存的大小。 (我知道缓存的实际大小将大于此)

MemLimitMB    MemLimitPct     AVG Cache MB on first expiry    
   1            NA              84
   2            NA              84
   3            NA              84
   6            NA              84
  NA             1              84
  NA             4              84
  NA            10              84
  10            20              81
  10            30              81
  10            39              82
  10            40              79
  10            49              146
  10            50              152
  10            60              212
  10            70              332
  10            80              429
  10           100              535
 100            39              81
 500            39              79
 900            39              83
1900            39              84
 900            41              81
 900            46              84

 900            49              1.8 GB approx. in task manager no mem errros
 200            49              156
 100            49              153
2000            60              214
   5            60              78
   6            60              76
   7           100              82
  10           100              541

这是测试应用程序:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
namespace FinalCacheTest
{       
    internal class Cache
    {
        private Object Statlock = new object();
        private int ItemCount;
        private long size;
        private MemoryCache MemCache;
        private CacheItemPolicy CIPOL = new CacheItemPolicy();

        public Cache(long CacheSize)
        {
            CIPOL.RemovedCallback = new CacheEntryRemovedCallback(CacheItemRemoved);
            NameValueCollection CacheSettings = new NameValueCollection(3);
            CacheSettings.Add("CacheMemoryLimitMegabytes", Convert.ToString(CacheSize)); 
            CacheSettings.Add("physicalMemoryLimitPercentage", Convert.ToString(49));  //set % here
            CacheSettings.Add("pollingInterval", Convert.ToString("00:00:10"));
            MemCache = new MemoryCache("TestCache", CacheSettings);
        }

        public void AddItem(string Name, string Value)
        {
            CacheItem CI = new CacheItem(Name, Value);
            MemCache.Add(CI, CIPOL);

            lock (Statlock)
            {
                ItemCount++;
                size = size + (Name.Length + Value.Length * 2);
            }

        }

        public void CacheItemRemoved(CacheEntryRemovedArguments Args)
        {
            Console.WriteLine("Cache contains {0} items. Size is {1} bytes", ItemCount, size);

            lock (Statlock)
            {
                ItemCount--;
                size = size - 108;
            }

            Console.ReadKey();
        }
    }
}

namespace FinalCacheTest
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            int MaxAdds = 5000000;
            Cache MyCache = new Cache(1); // set CacheMemoryLimitMegabytes

            for (int i = 0; i < MaxAdds; i++)
            {
                MyCache.AddItem(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
            }

            Console.WriteLine("Finished Adding Items to Cache");
        }
    }
}

为什么MemoryCache不遵守配置的内存限制?

trans by 2019-04-05T11:18:18Z

1 共1页