È a mia conoscenza che tutte le istanze di oggetti .NET iniziano con un 'intestazione dell'oggetto da 8 byte: un blocco di sincronizzazione (puntatore a 4 byte in una tabella SynchTableEntry) e un handle di tipo (puntatore a 4 byte nella tabella dei metodi dei tipi).Non vedere il blocco di sincronizzazione nel layout degli oggetti
Non lo vedo nelle finestre di memoria del debugger di VS 2010 RC (CLR 4.0).
Ecco una semplice classe che genererà un'istanza di 16 byte, meno l'intestazione dell'oggetto.
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;
}
}
Un dump di oggetto SOS mi dice che la dimensione totale dell'oggetto è di 24 byte. Ciò ha senso. La mia istanza da 16 byte più un'intestazione di oggetto da 8 byte.
!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
Ecco il ricordo grezzo:
0x0205B660 000d383c 00000003 00000000 0205b678 00000002 ...
e qui ci sono alcune annotazioni:
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
Il mio scopo inizia un indirizzo 0x0205B660. Ma posso contare solo 20 byte, il tipo handle e i campi istanza. Non c'è alcun segno di un puntatore del blocco di sincronizzazione. La dimensione dell'oggetto è riportata come 24 byte, ma il debugger sta mostrando che occupa solo 20 byte di memoria.
Sto leggendo Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects e mi aspetto che i primi 4 byte del mio oggetto siano un puntatore a blocco di sincronizzazione azzerato, come mostrato nella Figura 8 di tale articolo. Certo, questo è un articolo su CLR 1.1.
Mi stavo chiedendo se la differenza tra ciò che sto vedendo e ciò che questo articolo ha riportato è un cambiamento nella visualizzazione del layout di oggetti del debugger, o nel modo in cui il CLR espone gli oggetti nelle versioni successive alla 1.1 .
In ogni caso, qualcuno può rendere conto dei miei 4 byte mancanti?
Grazie CD. Hai ragione. 0x0205B660-0x4 mi porta all'intestazione dell'oggetto che contiene un indice di blocco di sincronizzazione, se ne viene impostato uno. Così ho bloccato il mio oggetto e ho eseguito: ! Syncblk 0x1 per ottenere il primo indice nella tabella dei blocchi di sincronizzazione. L'output mi fornisce l'indice del blocco di sincronizzazione, l'indirizzo e il proprietario (il mio oggetto). Quindi un riferimento a un oggetto fa riferimento al campo del tipo handle e (oggetto reference - 0x4) punta all'intestazione dell'oggetto, che contiene tutti i tipi di informazioni, a seconda del flusso di esecuzione. Ho appena preso "Advanced .NET Debugging" di Mario Hewardt e tratta questa roba in dettaglio. Grazie ancora. – user314045