.NET Framework 2.0 中的程式碼剖析
分析 API 在 .NET Framework 2.0 版中已予以改良,以提供額外的功能。 新功能會透過兩個新介面予以公開:ICorProfilerCallback2 和 ICorProfilerInfo2。
為 .NET Framework 1.0 版或 1.1 版所撰寫的分析工具 DLL,在 .NET Framework 2.0 Common Language Runtime (CLR) 環境中將無法正確地運作。 若要更新分析工具 DLL,使其能夠在 2.0 (含) 以後版本中使用,您必須實作 ICorProfilerCallback2 介面。 ICorProfilerInfo2 介面是繼承自 ICorProfilerInfo 介面,並會引入支援增強型 CLR 互動的新方法。
下列章節將討論這些變更:
泛型
程式碼分割
移除同處理序偵錯
使用原生映像產生器回呼
增強型記憶體回收回呼
凍結物件
其他 API 變更
除了 API 變更以外,也已加入新的 HRESULT、CORPROF_E_UNSUPPORTED_CALL_SEQUENCE。 如需可能傳回此 HRESULT 之情節的相關資訊,請參閱 CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT。
泛型
將泛型引入執行階段,會在分析 API 中造成三個變更:
在 typedef 語彙基元和 ClassID 值之間,或者 MethodDef 語彙基元和 FunctionID 值之間不再有一對一的對應。 這是因為每個類別或函式可能會執行個體化為數個不同的型別。 分析工具作者應該閱讀分析和執行階段通知識別碼、檢查如何在程式碼中使用 ICorProfilerInfo::GetClassFromToken 和 ICorProfilerInfo::GetFunctionFromToken 方法,並以泛型感知的方法重寫程式碼。 分析 API 會提供兩個新方法支援泛型:ICorProfilerInfo2::GetClassFromTokenAndTypeArgs 和 ICorProfilerInfo2::GetFunctionFromTokenAndTypeArgs。
FunctionID 和所包含的 ClassID 之間,不再有直接對應。 程式碼共用最佳化可讓泛型型別的不同執行個體化 (Instantiation) 共用程式碼。 只有當您在函式之特定啟動過程 (Activation) 的情境中檢查程式碼時,才可決定 FunctionID 的 ClassID。
ICorProfilerInfo 介面中現有的類別和函式資訊方法,不會提供泛型型別和函式之型別引數的相關資訊。 已針對這個目的提供 ICorProfilerInfo2::GetClassIDInfo2 和 ICorProfilerInfo2::GetFunctionInfo2 方法。 請注意,這些方法不會一直都提供此資訊,如需詳細資訊,請參閱分析和執行階段通知識別碼。
回到頁首
程式碼分割
.NET Framework 中的組件已進行效能最佳化。 預先編譯的機器碼已對每個函式分割成多個區域。 因此,現有的 ICorProfilerInfo::GetCodeInfo 方法無法再正確地描述函式之機器碼的延伸。 分析工具應該改為使用更一般的 ICorProfilerInfo2::GetCodeInfo2 方法。
回到頁首
移除同處理序偵錯
在 .NET Framework 2.0 中,同處理序 (In-Process) 偵錯已由一組與分析 API 一致的功能所取代。 也就是堆疊快照 (請參閱分析概觀) 和物件檢查功能。
回到頁首
使用原生映像產生器回呼
原生映像產生器 (NGen.exe) 中重要的最佳化,已從執行階段移到原生映像產生階段 (即使要花更多的功夫)。 這會造成在分析 API 的行為中發生下列變更:
對於大多數函式,JITCachedFunctionSearch 回呼將不再於原生映像中接收。 分析工具視使用回呼的方式而定,會有兩個選項可用:
如果分析工具使用回呼收集函式的資訊,則只有在程式執行期間先遇到該函式,分析工具才會切換到收集指定之函式相關資訊的配置。
如果分析工具使用回呼強制函式以 Just-in-Time (JIT) 編譯函式,以檢測目的之用,則會改用分析工具增強型原生映像。 如需詳細資訊,請參閱 分析 API 中的程式碼產生。
對於大多數型別,ClassLoad 回呼將不再於原生映像中接收。 分析工具應該針對這種類別,使用執行階段評估技術 (也稱為「延遲評估」(Lazy Evaluation))。 已使用分析工具增強型原生映像的分析工具,不需要變更其行為。 不過,除非分析工具因為其他原因而需要這些映像,則它不應該切換到分析工具增強型原生映像,因為分析工具增強型原生映像與一般映像大為不同。
回到頁首
增強型記憶體回收回呼
記憶體回收回呼已透過數種方法予以增強。 回呼現在會告知分析工具,已建立或終結了記憶體回收控制代碼,以及提供要結束之物件佇列的相關資訊,並使用 Collect 方法強制執行記憶體回收。 ICorProfilerCallback2::RootReferences2 方法 ( ICorProfilerCallback::RootReferences 的擴充) 會提供每個根型別的資訊。 最後,ICorProfilerCallback2::SurvivingReferences 方法會報告堆積中的物件配置,而這是由非壓縮記憶體回收所造成。
回到頁首
凍結物件
凍結物件是 .NET Framework 2.0 的新功能,是在原生映像產生階段初始化的常數物件,並會繫結至原生映像。 記憶體回收不會重新配置凍結物件,但記憶體回收物件可能會參考凍結物件。 新的 ICorProfilerInfo2::EnumModuleFrozenObjects 方法可讓分析工具列舉凍結物件。
回到頁首
其他 API 變更
.NET Framework 2.0 也包含下列 API 變更:
ICorProfilerInfo::SetFunctionReJIT 方法現在會傳回 E_NOIMPL。 在之前的版本中,呼叫這個方法會導致死結 (Deadlock)。
新的 ICorProfilerCallback2::ThreadNameChanged 方法會提供執行緒名稱變更的告知。
新的 ICorProfilerInfo2::GetThreadAppDomain 方法會接受執行緒 ID,並傳回該執行緒執行所在之應用程式定義域。
回到頁首