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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With