2010-04-11 26 views
5

Tüm .NET nesne örneklerinin bir 8 baytlık 'nesne başlığı' ile başlayacağı benim anlayışım: bir eşzamanlama bloğu (bir SynchTableEntry tablosuna 4 bayt işaretçi) ve bir tip tanıtıcı (4 bayt işaretçisi) tip yöntem tablosuna).Nesne Düzeninde Eşitleme Engelini Görmüyor

VS 2010 RC'nin (CLR 4.0) hata ayıklayıcı bellek pencerelerinde bunu göremiyorum.

Nesne başlığı daha az olan 16 baytlık bir örnek oluşturacak basit bir sınıf.

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; 
    } 
} 

Bir SOS nesne dökümü toplam nesne boyutu 24 bayt olduğunu söylüyor. Bu mantıklı. Benim 16 bayt örneğim artı bir 8 bayt nesne başlığı.

0x0205B660 000d383c 00000003 00000000 0205b678 00000002 ...

Ve burada bazı açıklamalar şunlardır:

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

Benim nesne adresi 0x0205B660 başlar

!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

İşte çiğ anı. Ancak bunun yalnızca 20 baytını, tip tanıtıcısını ve örnek alanlarını açıklayabilirim. Senkronizasyon blok işaretçisi belirtisi yok. Nesne boyutu 24 bayt olarak bildirilir, ancak hata ayıklayıcı yalnızca 20 bayt bellek kapladığını gösterir.

Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects okuyup, nesnemin ilk 4 baytının, bu makalenin Şekil 8'inde gösterildiği gibi sıfırlanmış bir eşzamanlama blok işaretçisi olmasını bekliyorum. Verilen, bu CLR 1.1 hakkında bir makale.

Sadece gördüğüm ve bu erken makale raporlarının arasındaki farkın, hata ayıklayıcının nesne düzeni görüntüsünde bir değişiklik mi yoksa CLR'nin 1.1'den sonraki sürümlerde nesneler oluşturduğu şekilde mi olduğunu merak ediyorum .

Neyse, 4 eksik bayttan sorumlu olan var mı?

cevap

8

Senkronizasyon bloğunun bellekteki nesne işaretçisinin "arkasında" olduğuna inanıyorum. Bu şekilde bir referans değişkeni doğrudan yöntem tablosuna işaret eder. Yani, 0x0205B660 adresindeki nesneniz için senkronizasyon bloğu 0x0205B65C adresinde olacaktır.

+2

Teşekkürler CD. Haklısın. 0x0205B660-0x4, ayarlanmışsa, bir eşzamanlama blok dizini içeren nesne başlığına ulaşır. Bu yüzden, nesnemi kilitledim ve eşzamanlama blok tablosunda ilk dizini almak için: ! Syncblk 0x1 . Çıktı bana senkronizasyon bloğu dizinini, adresini ve sahibini (nesnem) verir. Bu nedenle, bir nesne başvurusu, tür tanıtıcı alanına işaret eder ve (nesne başvurusu - 0x4), yürütme akışına bağlı olarak, her tür bilgiyi içeren nesne başlığına işaret eder. Sadece Mario Hewardt'ın "Gelişmiş. NET Hata Ayıklaması" nı kaldırdı ve bu ayrıntıları ayrıntılı olarak ele alıyor. Tekrar teşekkürler. – user314045