【问题标题】:List size each object take up in System.Runtime.Caching memory cache c#列出每个对象在 System.Runtime.Caching 内存缓存中占用的大小 c#
【发布时间】:2014-04-07 10:42:59
【问题描述】:

我正在使用 c# 内存缓存 (System.Runtime.Caching),它正在填满,并且使用的内存比预期的要多。 是否有列出缓存中每个对象在缓存中占用的大小

我想编写与此类似的代码,以便确定是哪个特定项目导致了问题?

private void ListSizeOfEachItemInCache()
{
    foreach {var item in Cache.Items}
    {
        Console.WriteLine(string.Format(item.Key, item.CacheSize));
    }
}

我的项目通常是其中包含集合的类,并且具有大型对象图。但是,如果我使用数据合同序列化程序将它们序列化到磁盘,它们似乎不会像在 RAM 中那样填充磁盘上的空间。这让我认为文件缓存可能会更好地工作(因为项目是从远程数据库中检索的 - 甚至不是本地数据库)。

private static readonly MemoryCache Cache = MemoryCache.Default;

我已经看到其他问题询问有关在内存中列出对象大小的问题,但这是不同的,因为我想要它在内存缓存中占用的确切大小(我不能假设它会完全相同,也许它还有一些其他开销,因为缓存需要知道一些其他数据,例如添加时间、到期策略等)..

【问题讨论】:

    标签: c# caching


    【解决方案1】:

    是的,你可能不会得到一个确切的数字。最好的办法是使用反射来迭代对象的层次结构并使用sizeof 计算所有值类型的大小。但这仍然不会告诉您确切的尺寸。

    对于我提到的那个例子,你可以使用这样的代码

    void Main()
    {
        var types = new List<object>{
            (byte)1,
            (short)1,
            (int)1,
            (long)1,
            (double)1,
            (decimal)1,
            (float)1,
            "omg afd obj amd",
            "omg afd obj amd omg afd obj amd omg afd obj amd omg afd obj amd omg afd obj amd omg afd obj amd omg afd obj amd ",
            new Exception("Holy Maceral"),
        };
    
        foreach(var o in types)
        {
            Console.WriteLine("Size of {0} == {1}",o.GetType().Name,o.SizeOf());
        }
    }
    public static class ExtensionMethods
    {
        public static int SizeOf(this object obj)
        {
            int size = 0;
            if(obj == null)
                return 0;
            Type type = obj.GetType();
    
            if(type.IsValueType)
            {
                return type.SizeOfType();
            }
    
            PropertyInfo[] info = type.GetProperties();
            foreach(PropertyInfo property in info)
            {
                if(property.GetIndexParameters().Length > 0)
                {
                    var ip = property.GetIndexParameters().First();
                    //Console.WriteLine(info);
                    var len = (int)info.FirstOrDefault(x=>x.Name == "Length" || x.Name == "Count").GetValue(obj);
                    for(var i = 0;i<len;i++)
                    {
                        size += property.GetValue(obj,new object[1]{i}).SizeOf();
                    }
                }
                else if(property.GetGetMethod().ReturnType.IsArray)
                {
                    var arr = property.GetGetMethod().Invoke(obj,null);
                    foreach(var a in (Array)arr)
                    {
                        size+= a.SizeOf();
                    }
                }
                else if(property.PropertyType.IsValueType)
                {
                    var val = property.GetValue(obj,null);
                    unsafe
                    {
                        size += property.PropertyType.SizeOfType();
                    }
                }
                else{
                    size += property.GetValue(obj,null).SizeOf();
                }
            }
            return size;
        }
    
        public static int SizeOfType(this Type type)
        {
            if(type.IsValueType == false)
                throw new ArgumentException("type must be value type");
    
            return Marshal.SizeOf(type);
        }
    }
    

    输出

    Size of Byte == 1
    Size of Int16 == 2
    Size of Int32 == 4
    Size of Int64 == 8
    Size of Double == 8
    Size of Decimal == 16
    Size of Single == 4
    Size of String == 19
    Size of String == 116
    Size of Exception == 36
    

    它不是 100% 完美的,如果不进行一些调整,可能无法对每个对象都起作用,但它应该可以确定哪个对象最具攻击性。

    【讨论】:

      猜你喜欢
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 2013-08-17
      • 1970-01-01
      相关资源
      最近更新 更多