对于任意实例(包括不同对象的集合,组合,单个对象等),如何确定其占用的字节数?
(我目前有一个包含各种对象的集合,并尝试确定它们的聚合大小)
编辑:是否有人编写了一种可为Object编写的扩展方法来完成此操作?我认为那会很不错。
对于任意实例(包括不同对象的集合,组合,单个对象等),如何确定其占用的字节数?
(我目前有一个包含各种对象的集合,并尝试确定它们的聚合大小)
编辑:是否有人编写了一种可为Object编写的扩展方法来完成此操作?我认为那会很不错。
Testing with string: 1234567
Hashtable<TestObject>: 184 672 704 B
Hashtable<TestObjectRef>: 136 668 560 B
Dictionary<int, TestObject>: 171 448 160 B
Dictionary<int, TestObjectRef>: 123 445 472 B
ConcurrentDictionary<int, TestObject>: 200 020 440 B
ConcurrentDictionary<int, TestObjectRef>: 152 026 208 B
HashSet<TestObject>: 149 893 216 B
HashSet<TestObjectRef>: 101 894 384 B
ConcurrentBag<TestObject>: 112 783 256 B
ConcurrentBag<TestObjectRef>: 64 777 632 B
Queue<TestObject>: 112 777 736 B
Queue<TestObjectRef>: 64 780 680 B
ConcurrentQueue<TestObject>: 112 784 136 B
ConcurrentQueue<TestObjectRef>: 64 783 536 B
ConcurrentStack<TestObject>: 128 005 072 B
ConcurrentStack<TestObjectRef>: 80 004 632 B
对于内存测试,我发现最好使用的是Original Answer。
GC.GetAllocatedBytesForCurrentThread()
对于值类型,可以使用Marshal.SizeOf
。当然,它返回将结构体在非托管内存中进行封送所需的字节数,这并不一定是CLR实际使用的。
如果您想要大致比较不同对象图/集合的大小,只需将其序列化为JSON即可 - 例如:
Console.WriteLine($"Size1:\t{(JsonConvert.SerializeObject(someBusyObject)).Length}")); Console.WriteLine($"Size2:\t{(JsonConvert.SerializeObject(someOtherObject)).Length}"));
在我的情况下,我正在测试登录时拉取的一堆 IEnumerable
,我只是想大致估算它们的大小以查看它们的相对重量。
这些都是昂贵的操作,并不会直接给出堆分配大小或类似的信息,但对于我的用例来说已经足够好了,并且很容易使用。
来自Pavel和jnm2:
private int DumpApproximateObjectSize(object toWeight)
{
return Marshal.ReadInt32(toWeight.GetType().TypeHandle.Value, 4);
}
顺便提一下,要小心,因为它只能与连续的内存对象一起使用。
最简单的方法是:int size = *((int*)type.TypeHandle.Value + 1)
[StructLayout(LayoutKind.Auto)]
在动态程序集中发出结构体,其中包含完全相同的字段并按相同顺序排列,使用sizeof IL指令获取其大小。您可能需要在结构体内发出一个静态方法,该方法简单地返回此值。然后添加2 * IntPtr.Size作为对象头。这应该给你准确的值。BindingFlags.DeclaredOnly
标志的字段来执行此操作。您可以使用反射来收集所有公共成员或属性信息(给定对象的类型)。但是,没有办法确定大小,除非遍历对象上的每个单独数据。