如何确定.NET中复杂对象的大小?

时间:2010-06-16 21:07:16

标签: c# .net memory memory-management

有没有办法确定.NET中复杂对象的总大小?此对象由其他对象组成,可能包含对其他复杂对象的引用。此对象封装的某些对象可能是POD,其他对象可能不是。

5 个答案:

答案 0 :(得分:10)

你所拥有的不是一个“复杂的对象”,而是一个对象图。要确定其总大小,您需要遍历该图 - 从一些根对象开始,并使用Reflection枚举引用类型的字段并检索它们的值(当然还要检查循环)。

要获取图表中特定对象的大小,请参阅this answer to a related question,但请注意,这是一个邪恶的黑客,完全不受支持,可能会中断(并且可能已经被破坏),并可能导致批发天堂般的小球种族灭绝。也就是说,没有“非hacky”方法来获得精确的值,因为它是一个定义的实现细节 - 你不应该对它有任何用处。为了在调试/分析期间找出应用程序的内存使用情况,黑客已经足够了。

答案 1 :(得分:4)

简单地说,没有办法知道。假设所有对象都是可序列化的,您可以使用BinaryFormatter将它们序列化为二进制blob,然后读取它的大小。但是,这将包括一些元数据,并膨胀实际的对象大小(但这将是一个合理的估计)。

对于值类型,您将使用Marshal.SizeOf(),只是它不考虑任何子对象。它会将任何内部引用类型计算为指向它的指针的大小。

反射是另一种方式,但不会暴露任何占用内存的私有成员。所以,除非我弄错了,否则没有办法真正做到这一点。

答案 2 :(得分:2)

...刁钻

如果两个对象指向相同的字符串变量,该怎么办?哪一个“拥有”字符串?听起来我需要模拟垃圾收集来获得真实的答案。重量不是很轻。

答案 3 :(得分:1)

System.Runtime.InteropServices.Marshal.SizeOf()一个镜头。

答案 4 :(得分:1)

以前在StackOverflow上的其他地方回答:

Find size of object instance in bytes in c#

您需要引入不安全的代码(由于此操作需要指针操作) - 代码如下所示:

static unsafe int CalcSize(object obj)
{
    RuntimeTypeHandle th = obj.GetType().TypeHandle;
    int size = *(*(int**)&th + 1);
    return size;
}

还要记住将项目设置(项目 - >构建选项卡)标记为“允许不安全的代码”。