2

找出对象在 .NET 中使用多少内存的最简单方法是什么?

最好不必求助于第三方工具。Marshal.SizeOf 或 sizeof 运算符看起来很有用,但仅适用于有限范围的类型。

一些相关的帖子:

4

3 回答 3

2

在这里问和回答:确定一个类使用多少内存?

快速总结是,如果您不想使用工具,则需要使用.NET Profiling API

Profiling API 非常强大,但我不认为它会被认为是“简单”的,所以我强烈建议使用内存分析工具——有些免费的可以,有些不行- 非常好的商业产品(特别是JetBrains dotTrace)。

于 2008-09-30T20:50:11.610 回答
0

你也可以这样做:

int startMem = GC.GetTotalMemory(true);
YourClass c = new YourClass();
int endMem = GC.GetTotalMemory(true);
int usedMeme = endMem - startMem;
于 2008-09-30T20:52:56.050 回答
0

由于 .NET 的垃圾收集特性,测量实际使用了多少内存有点困难。例如,如果你想测量一个类实例的大小,它是否包括你的实例所指向的实例所使用的内存?

如果答案是否定的,将所有字段的大小相加:使用反射,遍历类的所有成员;对 typeof(ValueType).IsAssignableFrom(member.Type) 的任何内容使用 Marshal.Sizeof(member.Type) - 这测量原始类型和结构,所有这些都驻留在类的实例分配中。每个引用类型(任何不能分配给值类型的)都将采用 IntPtr.Size。这有很多令人作呕的例外,但它可能对你有用。

如果答案是肯定的,你有一个严重的问题。多个事物可以引用单个实例,因此如果 'a' 和 'b' 都指向 'c',则将RecursiveSizeOf(a) + RecursiveSizeOf(b)大于SimpleSizeOf(a) + SimpleSizeOf(b) + SimpleSizeOf(c).

更糟糕的是,递归测量可能会导致您向下循环引用,或者将您带到您不打算测量的对象 - 例如,如果一个类正在引用互斥锁,则该互斥锁可能指向拥有它的线程。该线程可能指向它的所有局部变量,这些局部变量指向一些 C# 框架结构……您最终可能会测量整个程序。

它可能有助于理解像 C# 这样的垃圾收集语言在区分对象和内存单元的方式上有些“模糊”(从完全非技术意义上)。这是很多Marshal缓解措施 - 封送规则确保您正在封送(或测量)的结构具有明确定义的内存布局,因此具有明确定义的大小。在这种情况下,如果您打算使用 Marhsal.SizeOf(),则应该使用定义明确的可编组结构。

另一种选择是序列化。这不会具体告诉您正在使用多少内存,但它会让您对对象的大小有一个相对的了解。但是同样,为了序列化事物,它们必须具有明确定义的布局(因此也必须具有明确定义的大小)——您可以通过使类适当地可序列化来完成。

如果上述任何选项对您有吸引力,我可以发布实施示例。

于 2013-01-31T15:18:07.700 回答