在32位和64位的理解CLR对象的尺寸 [英] Understanding CLR object size between 32 bit vs 64 bit
问题描述
我想了解在32位和64位处理器的对象大小不同。比方说,我有一个简单的类
MyClass类
{
INT X;
诠释Ÿ;
}
因此,一个32位计算机上的整数,是4个字节。如果我添加同步块到它(另外4个字节),对象的大小将是12个字节。为什么会显示16个字节?
0:000>做0x029d8b98 名称:ConsoleApplication1.Program + MyClass的 方法表:000e33b0 EEClass:000e149c 尺寸:16(0×10)个字节 (C:\ MYTEMP \ ConsoleApplication1 \ ConsoleApplication1 \ BIN \ 86 \调试\ ConsoleApplication1.exe) 领域: MT字段偏移类型VT的Attr值名称 71972d70 4000003 4 System.Int32的1个实例0 X 71972d70 4000004 8 System.Int32的1个实例0是
在一个64位的机器,一个整数仍然是4字节唯一改变的是,同步块将是8个字节(如指针均为8个字节的64位机)。这意味着对象的大小将是16个字节。为什么会显示24个字节?
0:000>做0x00000000028f3c90 名称:ConsoleApplication1.Program + MyClass的 方法表:000007ff00043af8 EEClass:000007ff00182408 尺寸:24(为0x18)字节 (C:\ MYTEMP \ ConsoleApplication1 \ ConsoleApplication1 \斌\调试\ ConsoleApplication1.exe) 领域: MT字段偏移类型VT的Attr值名称 000007fef4edd998 4000003 8 System.Int32的1个实例0 X 000007fef4edd998 4000004ÇSystem.Int32的1个实例0是
的CLR可以自由地铺陈在内存中的对象,因为它认为合适的。这是一个实现细节。你不应该依赖于任何特定的布局。
你看到的差异是由于缺少类型句柄字段这也是CLR对象报头的一部分。此外,该字段可以被对齐字节边界
从<一个href="http://netinverse.com/devblogs/debugging/advanced-net-debugging-clr-objects-internal-structure/626/">Advanced净调试 - CLR对象的内部结构:
这是对象的CLR的内部结构是:
[DWORD:的SyncBlock] [DWORD:方法表指针] [DWORD:引用类型的指针] ... [数值类型字段值] ...
对象标题: [DWORD:的SyncBlock]
的对象指针: [DWORD:方法表指针] [DWORD:引用类型的指针] ... [数值类型字段值] ...每个对象是由一个ObjHeader pceded $ P $(在负偏移)。该ObjHeader的索引到的SyncBlock。
所以,你的目标很可能是布局是这样的:
86 的:(对齐到8字节)
Syncblk类型句柄X Y ------------,------------ | ------------,----------- - | 8月16日
64 的:(对齐到8字节)
Syncblk类型句柄XY ------------------------- | ------------------------ - | ------------,------------ | 8 16 24
另请参阅:钻成.NET框架内幕,看看如何在CLR创建运行时对象一>
I am trying to understand the object size difference between 32 bit and 64 bit processors. Let’s say I have a simple class
class MyClass
{
int x;
int y;
}
So on a 32 bit machine, an integer is 4 bytes. If I add the Syncblock into it ( another 4 bytes), the object size will be 12 bytes. Why is it showing 16 bytes?
0:000> !do 0x029d8b98 Name: ConsoleApplication1.Program+MyClass MethodTable: 000e33b0 EEClass: 000e149c Size: 16(0x10) bytes (C:\MyTemp\ConsoleApplication1\ConsoleApplication1\bin\x86\Debug\ConsoleApplication1.exe) Fields: MT Field Offset Type VT Attr Value Name 71972d70 4000003 4 System.Int32 1 instance 0 x 71972d70 4000004 8 System.Int32 1 instance 0 y
On a 64 bit machine, an integer is still 4 bytes the only thing changed is that Syncblock will be 8 bytes ( as pointers are 8 bytes on 64 bit machines). that mean the object size will be 16 bytes. Why is it showing 24 bytes?
0:000> !do 0x00000000028f3c90 Name: ConsoleApplication1.Program+MyClass MethodTable: 000007ff00043af8 EEClass: 000007ff00182408 Size: 24(0x18) bytes (C:\MyTemp\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe) Fields: MT Field Offset Type VT Attr Value Name 000007fef4edd998 4000003 8 System.Int32 1 instance 0 x 000007fef4edd998 4000004 c System.Int32 1 instance 0 y
The CLR is free to lay out objects in memory as it sees fit. It's an implementation detail. You should not rely on any specific layout.
The difference you see is due to the missing TypeHandle field which is also a part of the CLR object header. Additionally, the fields may be aligned to byte boundaries.
From Advanced .Net Debugging - CLR Object’s Internal Structure:
An object’s CLR internal structure is:
[DWORD: SyncBlock][DWORD: MethodTable Pointer][DWORD: Reference type pointer]…[Value of Value Type field]…
Object Header: [DWORD: SyncBlock]
Object Pointer: [DWORD: MethodTable Pointer][DWORD: Reference type pointer]…[Value of Value Type field]…Every Object is preceded by an ObjHeader (at a negative offset). The ObjHeader has an index to a SyncBlock.
So your object is likely laid out like this:
x86: (aligned to 8 bytes)
Syncblk TypeHandle X Y ------------,------------|------------,------------| 8 16
x64: (aligned to 8 bytes)
Syncblk TypeHandle X Y -------------------------|-------------------------|------------,------------| 8 16 24
See also: Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
这篇关于在32位和64位的理解CLR对象的尺寸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!