为什么WinDbg显示系统.Int32变量为24字节
本文关键字:24字节 变量 Int32 WinDbg 显示系统 为什么 | 更新日期: 2023-09-27 17:51:18
我正在使用WinDbg分析一个。net进程的内存转储,我注意到它报告了所有System的大小。堆上的Int32变量为24字节。下面是对其中一个变量进行相关DumpObj调用的示例:
0:000> !DumpObj /d 00000061c81c0e80
Name: System.Int32
MethodTable: 00007fff433f37c8
EEClass: 00007fff42e30130
Size: 24(0x18) bytes
File: C:'Windows'Microsoft.Net'assembly'GAC_64'mscorlib'v4.0_4.0.0.0__b77a5c561934e089'mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
00007fff433f37c8 4000456 8 System.Int32 1 instance 141 m_value
据我所知,大小系统。Int32应该是4字节。这种差异的来源是什么?
堆上的任何对象都有开销。在32位的MS.NET运行时,这是8个字节,在64位的运行时,这是16个字节(免责声明:这不是严格的契约,可能在将来或在一个符合。net运行时的实现中改变)。
由于您的int
是盒装的,因此它将具有16字节的开销。因此,您可能期望总共使用20个字节。嗯,除了在64位系统上,对象(和结构)被填充到8字节边界,所以每个int
实际上得到24字节。
相反,当您使用带有16个整数的struct
时,您将只使用16 + 4 * 16 = 80字节的内存,每个整数总共使用5字节。
再说一遍,这大部分是实现细节,所以不是你可以依赖的东西;一个有效的。net运行时完全有可能在1 MiB的内存中存储单个int
,如果它希望这样做,它也可以将其存储在一些紧凑的表示或实习中,只要它符合类型的所有契约行为。与实际的MS运行时实现相比,它也相当简化——例如,如果你的对象变得足够大,它将需要更多的开销。
它不是int32的大小做dd或dq地址,看到你的int32卡在第二个dword或qword
对于x86/x64,每个对象的隐式开销分别为12字节或24字节
0:004> .shell -ci "!DumpObj /d 01c72360" grep -i size
Size: 12(0xc) bytes
.shell: Process exited
0:004> dd 01c72360 l4
01c72360 5890c770 000001b5 80000000 5890afb0
0:004> .shell -ci "!DumpObj /d 01c72360" grep -i method
MethodTable: 5890c770
.shell: Process exited
0:004> .shell -ci "!DumpObj /d 01c72360" grep -i value
MT Field Offset Type VT Attr Value Name
5890c770 400044f 4 System.Int32 1 instance 437 m_value
.shell: Process exited
0:004> ? 1b5
Evaluate expression: 437 = 000001b5
将int32分开,让我们在x86
中剖析一个宽字符串"流"actualsizereqdfor(L"stream'0") = 7 * sizeof(wchar_t) == 7 * 2 == 0n14;
sizeof(method table ) == 0n04;
sizeof(sizeof(L"stream)) == 0n04;
sizeof(padding ?? terminator ?? whatever ?? ) == 0n04;
so total size == 0n26
dumpobj的结果
0:004> !DumpObj /d 01c73ad0
Name: System.String
MethodTable: 5890afb0
Size: 26(0x1a) bytes
String: stream
Fields:
MT Field Offset Type VT Attr Value Name
5890c770 40000aa 4 System.Int32 1 instance 6 m_stringLength
5890b9a8 40000ab 8 System.Char 1 instance 73 m_firstChar
5890afb0 40000ac c System.String 0 shared static Empty
原始显示
0:004> db 01c73ad0 l1a
01c73ad0 b0 af 90 58 06 00 00 00-73 00 74 00 72 00 65 00 ...X....s.t.r.e.
01c73ae0 61 00 6d 00 00 00 00 00-00 00 a.m.......