2014-06-22 53 views
2

目前我正在深入挖掘CLR並嘗試找到適當的管理對象大小。通過SOS調查CLR

我有兩個簡單類型:

XClass

class XClass 
{ 
    public XStruct StructField = new XStruct(); 
    public int IntField; 
    public double DoubleField; 
} 

XStruct

struct XStruct 
{ 
    public short ShortField; 
    public long LongField; 
} 

而且cosider代碼段這個對象涉及:

static unsafe void Main(string[] args) 
{ 
    double angle = 0.34; 

    { 
     double anotherDouble = 1.49; 

     XStruct xStruct = new XStruct(); 
     xStruct.ShortField = 12; 
     xStruct.LongField = 1234567890; 

     XClass classObject = new XClass(); 
     classObject.DoubleField = angle + anotherDouble; 
     classObject.IntField = 123; 
     classObject.StructField = xStruct; 

     <<<<<<<<BREAKPOINT>>>>>>> 

     xStruct.ShortField = 3; 
    } 

    double* ptr = &angle; 

    Console.WriteLine(*(ptr - 1)); 
    Console.ReadKey(); 
} 

因此,我嘗試獲取有關XStruct放置在堆棧中的一些信息,但是我無法在其中找到它。

!dso 
PDB symbol for clr.dll not loaded 
OS Thread Id: 0x1f94 (8084) 
ESP/REG Object Name 
0018EF1C 0260252c ConsoleApplication2.XClass 
0018EF20 0260252c ConsoleApplication2.XClass 
0018F290 0260252c ConsoleApplication2.XClass 
0018F2C4 0260251c System.Object[] (System.String[]) 
0018F2E0 0260252c ConsoleApplication2.XClass 
0018F2E8 0260252c ConsoleApplication2.XClass 
0018F30C 0260251c System.Object[] (System.String[]) 
0018F3C0 0260251c System.Object[] (System.String[]) 
0018F51C 0260251c System.Object[] (System.String[]) 
0018F554 0260251c System.Object[] (System.String[]) 
0018FA90 026System.SharedStatics 

請解釋爲什麼不顯示ConsoleApplication2.XStruct爲什麼ConsoleApplication2.XClass顯示爲棧對象。我認爲XClass(作爲正常的參考類型)應該放在堆中。或者可能是我對!dso的理解不正確。

謝謝。

+0

您可以查看對象大小的元數據。在這裏你可以找到代碼。 https://github.com/mumusan/dotnetex –

+0

@Dmitry Dovgopoly:我不是在尋找XStruct的大小。我感興趣的是爲什麼它不顯示爲堆棧對象。 – frankie

+0

它沒有打印出你的雙變量。顯然,值類型的本地不打印。 http://msdn.microsoft.com/en-us/library/bb190764(v=vs.110).aspx – usr

回答

3

!dso ==轉儲堆棧對象。專注於「對象」,結構不是一個對象。

SOS能夠找到對象引用的唯一原因是因爲它可以使用編譯方法時抖動產生的元數據。垃圾收集器在執行堆棧遍歷以找回對象引用時使用此數據。您可以在this answer中閱讀更多內容。此元數據中缺少值類型值,GC不關心它們。

您可以通過創建一個結構體的數組來推斷結構體的大小,給結構體的第一個字段一個獨特的值。使用VS調試器Debug + Windows + Memory + Memory1查看陣列,將變量名稱放在Address字段中。您將結構值返回到十六進制轉儲中,位於數組標題之後。請注意,結構大小取決於CLR版本和過程的位數,因此只能將此信息用作提示。

+0

任何原因,特別是不只是使用'sizeof(XStruct)'? – Janiels

+0

當然,它不適用於任何具有引用類型字段的結構類型。 –

+0

因爲你不能聲明指向非非託管類型的指針,所以你也不是。 – Janiels