简体   繁体   English

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

[英]Ways to determine size of complex object in .NET?

Are there ways at determining the total size of a complex object in .NET? 有没有办法确定.NET中复杂对象的总大小? This object is composed of other objects and might hold references to other complex objects. 此对象由其他对象组成,可能包含对其他复杂对象的引用。 Some of the objects encapsulated by this object might be POD, others may not. 此对象封装的某些对象可能是POD,其他对象可能不是。

What you have is not a "complex object", it's an object graph. 你拥有的不是一个“复杂的对象”,而是一个对象图。 To determine its total size, you need to walk that graph - starting with some root object, and using Reflection to enumerate fields of reference types and retrieving their values (and checking for loops, of course). 要确定其总大小,您需要遍历该图 - 从一些根对象开始,并使用Reflection枚举引用类型的字段并检索它们的值(当然,检查循环)。

To get the size of a particular object in the graph, see this answer to a related question , but note that this is an evil hack, completely unsupported, may break (and may already be broken), and may result in a wholesale kitten genocide in heavenly spheres. 要获得图表中特定对象的大小,请参阅相关问题的答案 ,但请注意,这是一个邪恶的黑客,完全不受支持,可能会破坏(并且可能已经被破坏),并可能导致批发小猫种族灭绝在天上的领域。 That said, there is no "non-hacky" way to get a precise value, because it is an implementation detail by definition - you shouldn't have any use for it. 也就是说,没有“非hacky”方法来获得精确的值,因为它是一个定义的实现细节 - 你不应该对它有任何用处。 And for the purpose of finding out the memory usage of an app during debugging/profiling, the hack is good enough. 并且为了在调试/分析期间找出应用程序的内存使用情况,黑客已经足够了。

Put simply, there is no way to know. 简而言之,没有办法知道。 Assuming all the objects are serializable, you could use a BinaryFormatter to serialize them into a binary blob, and then read the size of that. 假设所有对象都是可序列化的,您可以使用BinaryFormatter将它们序列化为二进制blob,然后读取它的大小。 However, this would include some metadata, and inflate the actual object size (but it would be a reasonable estimate). 但是,这将包括一些元数据,并膨胀实际的对象大小(但这将是一个合理的估计)。

For value types, you would use Marshal.SizeOf() , only it does not take into account any subobjects. 对于值类型,您将使用Marshal.SizeOf() ,只是它不考虑任何子对象。 It would calculate any internal reference type as the size of the pointer to it. 它会将任何内部引用类型计算为指向它的指针的大小。

Reflection is another way, but would not expose any private members taking up memory. 反思是另一种方式,但不会暴露任何私人成员占用记忆。 So, unless I'm mistaken, there is no way to really do this properly. 所以,除非我弄错了,否则没有办法真正做到这一点。

Tricky... 整蛊......

What if two objects point to the same string variable. 如果两个对象指向相同的字符串变量,该怎么办? Which one "owns" the string? 哪一个“拥有”字符串? It sounds to me you need to simulate a garbage collection to get a true answer. 听起来我需要模拟垃圾收集来获得真实的答案。 Not exactly light weight. 重量不是很轻。

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

Previously answered elsewhere on StackOverflow: 以前在StackOverflow上的其他地方回答:

Find size of object instance in bytes in c# 在c#中以字节为单位查找对象实例的大小

You need to introduce unsafe code (due to pointer operations required for this) - the code looks like this: 你需要引入不安全的代码(由于这需要指针操作) - 代码如下所示:

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

Also remember to mark the project settings (Project->Build tab) to "Allow unsafe code". 还要记住将项目设置(项目 - >构建选项卡)标记为“允许不安全的代码”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM