找出.net对象的大小

我试图找出多less内存我的对象需要看看有多less人在大对象堆(这是任何超过85,000字节)结束。

是简单的为int添加4,长为8,为每个对象的任何引用types等4,或者如果你是在64位8,或者有方法,属性等开销

不要忘记,实际对象的大小不包括它引用的任何对象的大小。

大型对象堆中唯一可能发生的事情是数组和string – 其他对象往往本身相对较小。 即使是一个拥有10个引用typesvariables(每个在x86上4个字节)和10个GUID(每个16个字节)的对象也只会占用大约208个字节(对于types引用和同步块有一点开销)。

同样,当考虑一个数组的大小时,不要忘记,如果元素types是一个引用types,那么它只是数组本身的引用大小。 换句话说,即使你有一个有20000个元素的数组,即使它引用了更多的数据,数组对象本身的大小也只会超过80K(在x86上)。

请按照这些步骤来获取对象的大小。

1)转到Visual Studio(2010)项目属性 – >debugging选项卡 – >启用非托pipe代码debugging。

2)转到Visual Studiodebugging菜单 – >选项和设置 – >debugging – >符号。

3)在那里启用Microsoft Symbol Server,保留默认值(符号可以开始下载)

4)在你的代码中设置断点,开始debugging(F5)。

5)打开debugging – > Windows – >立即窗口。

6)input.load sos.dll(Strike的儿子)

7)input!DumpHeap -type MyClass(你想要查找的对象大小)

8)从输出中找出对象的地址即(00a8197c)

地址MT大小00a8197c 00955124 36

9)接下来,!ObjSize 00a8197c

10)你去 – > sizeof(00a8197c)= 12(0x48)字节(MyClass)

您正在进入高级.NETdebugging领域。 从John Robins开始debugging书籍 。

使用WinDBG与Sos.dll(.NET分发的一部分)和Sosex.dll扩展。 使用这些工具,您可以真正看到当您的应用程序运行时发生了什么。 你会find你上面提到的问题的答案。

(另一个build议是安装Shared Source CLI 2.0 ,也就是Rotor 2,看看底下是怎么回事。)

如果可以的话 – 序列化它!

 Dim myObjectSize As Long Dim ms As New IO.MemoryStream Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter() bf.Serialize(ms, myObject) myObjectSize = ms.Position 

戈麦斯的方法简化了:

  1. 转到Visual Studio(2010)项目属性 – >debugging选项卡 – >启用非托pipe代码debugging。

  2. 在代码中设置断点,开始debugging(F5)。

  3. 打开debugging – > Windows – >立即窗口。

  4. input.load sos

  5. input(用您的对象的名称replacemyObject)

? String.Format(“{0:x}”,Integer.Parse(System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject(System.Runtime.InteropServices.GCHandle.Alloc( myObject ).GetHandleValue())。ToString()) – 4 )

6.使用结果作为!ObjSize的参数

请参阅: SOS.DLL,对象地址和Visual Studiodebugging器简介

示例(我们正在寻找名为tbl对象):

 .load sos extension C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll loaded ? string.Format("{0:x}",Integer.Parse(System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject(System.Runtime.InteropServices.GCHandle.Alloc(tbl).GetHandleValue()).ToString())-4) "27ccb18" !ObjSize 27ccb18 PDB symbol for clr.dll not loaded sizeof(027ccb18) = 154504 ( 0x25b88) bytes (System.Data.DataTable) 

除非它是一个巨大的值types或实例types(即数千个字段),否则唯一需要担心的types是大数组或string。 当然,要弄清楚数组的大小,你需要知道元素的大小。

.NET(当前)以类似于本地编译器alignmenttypes的方式alignmenttypes。 基本types具有自然alignment,通常是两个最接近其大小的四舍五入整数次幂:

 Single, Int32, UInt32 - 4 IntPtr, UIntPtr, pointers, references - 4 on 32-bit, 8 on 64-bit Double, Int64, UInt64 - 8 Char, Int16, UInt16 - 2 Byte, SByte - 1 

在组装types时,编译器将确保任何给定types的所有字段的实例内的起始偏移量都与匹配该types的边界alignment – 假设显式布局未被使用。

用户定义的types本身有一个alignment方式,它被计算为任何字段types的最高alignment方式。 如果需要,types的大小也会扩展,以使types的大小也一致。

但是,当然,所有引用types仍然只有IntPtr.Size的大小和alignment方式,所以引用types的大小不会影响该types的数组。

请注意,CLR可以根据自己的判断select不同于上述的布局types,也许可以增加caching位置或减lessalignment所需的填充。

作为一个估计(在2017年),您可以debugging到您的应用程序,在字典开始生效之前设置一个断点,进入“Memory Usage Snapshot”(标签:诊断工具下的内存使用情况),填写字典并获得另一个快照 – 不是确切地说是一个好的gestimate。