Understanding CLR object size between 32 bit vs 64 bit

半世苍凉 提交于 2019-12-29 03:57:24

问题


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  

回答1:


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




回答2:


The sync block sits at a negative offset from the object pointer. The first field at offset 0 is the method table pointer, 8 bytes on x64. So on x86 it is SB + MT + X + Y = 4 + 4 + 4 + 4 = 16 bytes. The sync block index is still 4 bytes in x64. But the object header also participates in the garbage collected heap, acting as a node in a linked list after it is released. That requires a back and a forward pointer, each 8 bytes in x64, thus requiring 8 bytes before the object pointer. 8 + 8 + 4 + 4 = 24 bytes.




回答3:


Objects have some overhead beyond the member variables. In 32-bit implementations of .NET, the allocation overhead appears to be 12 bytes. As I recall, it's 16 bytes in the 64 bit runtime.

In addition, object allocations are aligned on the next 8 byte boundary.




回答4:


Seems to me, any object should have some kind of pointer to its class. That'd account for your extra 4 or 8 bytes.

The layout of an object is really an implementation thing, though. If you care about the layout, there are attributes designed to explicitly tell .net where and how you want the members positioned. Check out StructLayoutAttribute.



来源:https://stackoverflow.com/questions/3815227/understanding-clr-object-size-between-32-bit-vs-64-bit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!