编程找出内存使用对象 [英] programmatically find memory used by object

查看:141
本文介绍了编程找出内存使用对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法以编程方式准确判断的内存在C#中的对象使用的金额是多少?我不关心这个过程有多慢的,因此运行选区左右是可以接受的(当然我喜欢的东西更有效)。

Is there a way to programmatically and accurately determine the amount of memory used by an object in c#? I am not concerned with how slow the process is, so running GCs left and right is acceptable (of course I'd prefer something more efficient).


  • 序列化对象,看着由此产生的长度似乎并不十分准确(在此方法中的一个简单的测试,我看到一个整数返回54的值)。

  • Serializing objects and looking at the resulting length doesn't seem very accurate (in a simple test of this method, I saw that an integer returned a value of 54).

使用 GC.GetTotalMemory(真)似乎产生不一致的值,更何况他们似乎太大了。

Using GC.GetTotalMemory(true) seems to produce inconsistent values, not to mention they appear too large.

使用 Marshal.SizeOf(对象)产生精确的结果,但只出现与原语的工作。

Using Marshal.SizeOf(object) produces accurate results, but only appears to work with primitives.

如果没有沿着这些线路是可用的,一种替代方案是,计算基于所使用的结构和所涉及的基元的大小。这也是可以接受的(虽然镦粗),但我需要知道计算对象管理费用等任何文献,将显示我的方式做这将是真棒的正确的方法。

If nothing along those lines is available, an alternative would be to calculate sizes based on the structures used and the primitives involved. This would also be acceptable (though upsetting), but I'd need to know the correct method of calculating object overheads, etc. Any literature that would show me a way to do this would be awesome.

相似,所以问题(其中没有一个似乎对物体大小的精确计算具体方法):

Similar SO questions (none of which seemed to have concrete methods for accurate calculation of object size):

How多的内存做了C#/。NET的对象使用?

如何获得可用内存或在C#中使用

如何在内存中获取物体的大小?

的sizeof(),相当于为引用类型

工具来分析内存(非编程方法):

Tools to profile memory (non-programmatic approach):

http://www.microsoft .COM / EN-US /下载/ details.aspx?ID = 16273

找出多少内存正在使用的对象在C#中?

推荐答案

另一个想法是通过反射物体有一个辅助类要做到这一点,并提取其所有数据成员和sizeof的收集所有领域的大小(),这将是一个有点复杂,但它是可实现的。

another idea is to have a helper class to do this by reflecting the object and extract its all data members and gather all fields size by sizeof() , it will be a little bit complicated but it is implementable

这个类将计算对象的实际大小,但我还只是测试它几次,几个对象进行了测试,但我想我会的工作。

this class will calculate the actual size of an object , but i have tested it just a few times and a few objects were tested but i think i will be working.

public class SizeHelper
{
    private static int GetTypeSizeArray(string typeName, object objValue)
    {
        switch (typeName)
        {
            case "System.Double[]":
                return sizeof(System.Double) * ((System.Double[]) objValue).Length ;
            case "System.Single[]":
                return sizeof(System.Single) * ((System.Single[])objValue).Length;
            case "System.Char[]":
                return sizeof(System.Char) * ((System.Char[])objValue).Length;
            case "System.Int16[]":
                return sizeof(System.Int16) * ((System.Int16[])objValue).Length;
            case "System.Int32[]":
                return sizeof(System.Int32) * ((System.Int32[])objValue).Length;
            case "System.Int64[]":
                return sizeof(System.Int64) * ((System.Int64[])objValue).Length;
            case "System.UInt16[]":
                return sizeof(System.UInt16) * ((System.UInt16[])objValue).Length;
            case "System.UInt32[]":
                return sizeof(System.UInt32) * ((System.UInt32[])objValue).Length;
            case "System.UInt64[]":
                return sizeof(System.UInt64) * ((System.UInt64[])objValue).Length;
            case "System.Decimal[]":
                return sizeof(System.Decimal) * ((System.Decimal[])objValue).Length;
            case "System.Byte[]":
                return sizeof(System.Byte) * ((System.Byte[])objValue).Length;
            case "System.SByte[]":
                return sizeof(System.SByte) * ((System.SByte[])objValue).Length;
            case "System.Boolean":
                return sizeof (System.Boolean)*((System.Boolean[]) objValue).Length;
            default:
                return 0;
        }
    }

    public static int GetSize(object obj)
    {
        Type t = obj.GetType();

        FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
        int size = 0;
        foreach (FieldInfo fieldInfo in fields)
        {
            if (fieldInfo.FieldType.BaseType.FullName.Equals("System.ValueType"))
            {
                size += GetTypeSize(fieldInfo.FieldType.FullName);
            }
            else if (fieldInfo.FieldType.BaseType.FullName.Equals("System.Array"))
            {
                var subObj = fieldInfo.GetValue(obj);
                if (subObj != null)
                    size += GetTypeSizeArray(fieldInfo.FieldType.FullName, subObj);
            }
            else if(fieldInfo.FieldType.FullName.Equals("System.String"))
            {
                var subObj = fieldInfo.GetValue(obj);
                if (subObj != null)
                {
                    size += subObj.ToString().Length*sizeof (System.Char);
                }
            }
            else
            {
                var subObj = fieldInfo.GetValue(obj);
                if (subObj != null)
                    size += GetSize(subObj);
            }
        }
        return size;
    }

    private static int GetTypeSize(string typeName)
    {
        switch (typeName)
        {
            case "System.Double":
                return sizeof(System.Double);
            case "System.Single":
                return sizeof(System.Single);
            case "System.Char":
                return sizeof(System.Char);
            case "System.Int16":
                return sizeof(System.Int16);
            case "System.Int32":
                return sizeof(System.Int32);
            case "System.Int64":
                return sizeof(System.Int64);
            case "System.UInt16":
                return sizeof(System.UInt16);
            case "System.UInt32":
                return sizeof(System.UInt32);
            case "System.UInt64":
                return sizeof(System.UInt64);
            case "System.Decimal":
                return sizeof(System.Decimal);
            case "System.Byte":
                return sizeof(System.Byte);
            case "System.SByte":
                return sizeof(System.SByte);
             case "System.Boolean":
                return sizeof (System.Boolean);
            default:
                return 0;
        }
    }
}

这篇关于编程找出内存使用对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆