分析 API 的物件檢查
本主題說明如何使用程式碼剖析方法來檢查物件。
FunctionEnter2 和 FunctionLeave2 回呼
FunctionEnter2 和 FunctionLeave2 回呼會提供引數與函式傳回值的相關資訊,並當做記憶體區域。 引數會在指定的記憶體區域中,由左至右存放。 分析工具可以使用函式的中繼資料簽章來解譯引數,如下表所示。
ELEMENT_TYPE |
表示 |
---|---|
基本型別 (ELEMENT_TYPE <= R8、I、U) |
基本值。 |
實值型別 (VALUETYPE) |
視型別而定。 |
參考型別 (CLASS、STRING、OBJECT、ARRAY、GENERICINST、SZARRAY) |
ObjectID (指向記憶體回收堆積內的指標)。 |
BYREF |
Managed 指標 (而非 ObjectID,但可能指向堆疊或記憶體回收堆積)。 |
PTR |
Unmanaged 指標 (無法使用記憶體回收來移動)。 |
FNPTR |
指標大小的不透明值。 |
TYPEDBYREF |
Managed 指標,隨後接著指標大小的不透明值。 |
ObjectID 和 Managed 指標之間的差異如下:
ObjectID 僅會指向記憶體回收堆積或凍結物件堆積。 Managed 指標也可能會指向堆疊。
ObjectID 永遠會指向物件的開頭。 Managed 指標可能會指向其中一個物件的欄位。
Managed 指標無法傳遞至預期 ObjectID 的函式。
如需可用 CLR 型別的清單,請參閱 CorElementType 列舉型別。
檢查複雜型別
檢查參考型別或非基本實值型別牽涉到一些進階技術。
針對字串或陣列以外的實值型別和參考型別,ICorProfilerInfo2::GetClassLayout 方法會提供每個欄位的位移 (Offset)。 分析工具接著可以使用中繼資料,判斷欄位的型別並以遞迴方式加以評估。
注意事項 |
---|
GetClassLayout 只會傳回類別本身所定義的欄位,父類別所定義的欄位則不包括在內。您可以使用 ICorProfilerInfo2::GetClassIDInfo2 方法尋找父類別的 ClassID,然後使用 GetClassLayout 取得父類別所定義的欄位相關資訊。 |
針對 Boxed 實值型別,ICorProfilerInfo2::GetBoxClassLayout 方法會提供方塊內實值型別的位移。 實值型別本身的配置則不會變更。 因此,只要分析工具在方塊內找到實值型別,就可以使用 GetClassLayout 來了解其配置。
若是字串,ICorProfilerInfo2::GetStringLayout 方法會在字串物件中提供所需資料片段的位移。
陣列的特殊之處在於,您必須為每個陣列物件 (而不是每個陣列型別) 呼叫方法 (這是因為有太多陣列格式需要使用位移來描述)。會提供 ICorProfilerInfo2::GetArrayObjectInfo 方法以執行轉譯。
檢查靜態欄位
靜態欄位有四種類型。 下表將說明這些欄位以及識別的方式。
靜態類型 |
定義 |
出現在中繼資料內的方式 |
---|---|---|
AppDomain |
您的基本靜態欄位。 在每個應用程式定義域中的值都不同。 |
沒有附加之自訂屬性的靜態欄位。 |
執行緒 |
Managed 執行緒區域儲存區 (TLS)。 這是對於每個執行緒和每個應用程式定義域,具有唯一值的靜態欄位。 |
以 ThreadStaticAttribute 標記的靜態欄位。 |
RVA |
在模組的資料區段中,具有開頭之處理序範圍內的靜態欄位。 |
具有 hasRVA 旗標的靜態欄位。 |
內容 |
在每個 COM+ 內容中具有不同值的靜態欄位。 |
以 ContextStaticAttribute 標記的靜態欄位。 |
ICorProfilerInfo2::GetThreadStaticAddress、ICorProfilerInfo2::GetAppDomainStaticAddress、ICorProfilerInfo2::GetContextStaticAddress 和 ICorProfilerInfo2::GetRVAStaticAddress 方法都會提供靜態欄位的位置相關資訊。 在該位置查看記憶體時,請解譯如下:
參考型別:ObjectID。
實值型別:包含實際值之方塊的 ObjectID。
基本型別:基本值。
參考資料
ICorProfilerInfo2::GetClassLayout 方法
ICorProfilerInfo2::GetBoxClassLayout 方法
ICorProfilerInfo2::GetStringLayout 方法
ICorProfilerInfo2::GetArrayObjectInfo 方法
ICorProfilerInfo2::GetThreadStaticAddress 方法
ICorProfilerInfo2::GetAppDomainStaticAddress 方法
ICorProfilerInfo2::GetContextStaticAddress 方法
ICorProfilerInfo2::GetRVAStaticAddress 方法