我试图找出我的对象需要多少内存才能看到它们中有多少内存在大对象堆上(超过85,000字节).
对于每个对象的任何引用类型等,添加4为int,8为长,4(或8如果你在64位)是简单的,或者是方法,属性等的开销.
不要忘记实际对象的大小不包括它引用的任何对象的大小.
唯一可能最终出现在大对象堆上的东西是数组和字符串 - 其他对象本身往往相对较小.即使是具有(例如)10个引用类型变量(x86上各4个字节)和10个GUID(每个16字节)的对象也只占用大约208个字节(类型引用和同步块有一些开销).
同样在考虑数组的大小时,不要忘记如果元素类型是引用类型,那么它只是数组本身的引用大小.换句话说,即使你有一个包含20,000个元素的数组,数组对象本身的大小也只会超过80K(在x86上),即使它引用了更多的数据.
请按照以下步骤获取对象的大小.
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)
如果可以 - 序列化它!
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
您正在进入高级.NET调试领域.从John Robins调试书籍开始.
将WinDBG与Sos.dll(.NET发行版的一部分)和Sosex.dll扩展一起使用.使用这些工具,您可以真正了解应用程序运行时发生的情况.您将找到上述问题的答案.
(另一个建议是安装Shared Source CLI 2.0,又称Rotor 2,以了解幕后发生了什么.)
Gomes的方法简化了:
转到Visual Studio(2010)项目属性 - >调试选项卡 - >启用非托管代码调试.
在代码中设置断点,开始调试(F5).
打开调试 - > Windows - >立即窗口.
输入.load sos
输入(用对象名称替换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)