It's my understanding that all .NET object instances begin with an 8 byte 'object header': a synch block (4 byte pointer into a SynchTableEntry table), and a type handle (4 byte pointer into the types method table).
I'm not seeing this in VS 2010 RC's (CLR 4.0) debugger memory windows.
Here's a simple class that will generate a 16 byte instance, less the object header.
class Program
{
short myInt = 2; // 4 bytes
long myLong = 3; // 8 bytes
string myString = "aString"; // 4 byte object reference
// 16 byte instance
static void Main(string[] args)
{
new Program();
return;
}
}
An SOS object dump tells me that the total object size is 24 bytes. That makes sense. My 16 byte instance plus an 8 byte object header.
!DumpObj 0205b660 Name: Offset_Test.Program MethodTable: 000d383c EEClass: 000d13f8 Size: 24(0x18) bytes File: C:\Users\Bob\Desktop\Offset_Test\Offset_Test\bin\Debug\Offset_Test.exe Fields: MT Field Offset Type VT Attr Value Name 632020fc 4000001 10 System.Int16 1 instance 2 myInt 632050d8 4000002 4 System.Int64 1 instance 3 myLong 631fd2b8 4000003 c System.String 0 instance 0205b678 myString
Here's the raw memory:
0x0205B660 000d383c 00000003 00000000 0205b678 00000002 ...
And here are some annotations:
offset 0 000d383c ;TypeHandle (pointer to MethodTable), 4 bytes offset 4 00000003 00000000 ;myLong, 8 bytes offset 12 0205b678 ;myString, 4 byte reference to address of "myString" on GC Heap offset 16 00000002 ;myInt, 4 bytes
My object begins a address 0x0205B660. But I can only account for 20 bytes of it, the type handle and the instance fields. There is no sign of a synch block pointer. The object size is reported as 24 bytes, but the debugger is showing that it only occupies 20 bytes of memory.
I'm reading Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects, and expected the first 4 bytes of my object to be a zeroed synch block pointer, as shown in Figure 8 of that article. Granted, this is an article about CLR 1.1.
I'm just wondering if the difference between what I'm seeing and what this early article reports is a change in either the debugger's display of object layout, or in the way the CLR lays out objects in versions later than 1.1.
Anyway, can anyone account for my 4 missing bytes?
Causes: The block was inserted onto a layer that is turned off or frozen. One of the layers used in the block is turned off or frozen in the parent drawing. The block file is corrupted.
Invisible attributes Right-click the block and choose Block Editor. Select the attributes (use the QSELECT command if there are many). In the Properties palette, change Invisible to No. Close the Block Editor and save the block.
If you want to see all of the attributes, on the Insert ribbon, expand the Block panel, click the Retain Attribute Display button, and choose Display All Attributes. This causes all attributes to become visible the next time you regenerate the drawing, regardless of their visibility setting.
I believe the sync block is "behind" the object pointer in memory. That way a reference variable points directly to the method table. So, for your object at address 0x0205B660, the sync block would be at address 0x0205B65C.
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