找出.net对象的大小

Mat*_*les 53 .net profiling garbage-collection memory-management

我试图找出我的对象需要多少内存才能看到它们中有多少内存在大对象堆上(超过85,000字节).

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

Jon*_*eet 52

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

唯一可能最终出现在大对象堆上的东西是数组和字符串 - 其他对象本身往往相对较小.即使是具有(例如)10个引用类型变量(x86上各4个字节)和10个GUID(每个16字节)的对象也只占用大约208个字节(类型引用和同步块有一些开销).

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


Gom*_*mes 35

请按照以下步骤获取对象的大小.

1)转到Visual Studio(2010)项目属性 - >调试选项卡 - >启用非托管代码调试.

2)转到Visual Studio Debug菜单 - > Option and Settings - > Debugging - > Symbols.

3)启用Microsoft Symbol Server,保留默认值.(符号可能开始下载)

4)在代码中设置断点,开始调试(F5).

5)打开调试 - > Windows - >立即窗口.

6)输入.load sos.dll(罢工之子)

7)输入!DumpHeap -type MyClass(要查找的对象大小)

8)从输出定位对象的地址即(00a8197c)

地址MT大小00a8197c 00955124 36

9)接下来,!ObjSize 00a8197c

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

  • 不知道你可以在visual studio中使用sos.dll.非常有用,谢谢.另外可能有用的是注意,如果应用程序处于64位模式,则不会加载sos.dll.请参见http://stackoverflow.com/a/3548129/442078 (6认同)

ser*_*hio 10

如果可以 - 序列化它!

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
Run Code Online (Sandbox Code Playgroud)

  • +1因为这是我实际想要找到的(不仅仅是参考文献的大小) (3认同)
  • @MatthewSteeples,一个没有组件的对象,它是一个空对象,所以如果你想要容器的“大小”,它应该包括组件的大小。 (2认同)

Dav*_*uda 9

您正在进入高级.NET调试领域.从John Robins调试书籍开始.

WinDBG与Sos.dll(.NET发行版的一部分)和Sosex.dll扩展一起使用.使用这些工具,您可以真正了解应用程序运行时发生的情况.您将找到上述问题的答案.

(另一个建议是安装Shared Source CLI 2.0,又称Rotor 2,以了解幕后发生了什么.)


Iva*_*anH 5

Gomes的方法简化了:

  1. 转到Visual Studio(2010)项目属性 - >调试选项卡 - >启用非托管代码调试.

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

  3. 打开调试 - > Windows - >立即窗口.

  4. 输入.load sos

  5. 输入(用对象名称替换myObject)

?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 Studio调试器简介

示例(我们正在寻找名为的对象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)
Run Code Online (Sandbox Code Playgroud)