分析 API 中的程式碼產生
本主題將說明 Microsoft Intermediate Language (MSIL) 程式碼到機器碼的流程,並描述分析工具控制程式碼產生的方式。
自動與手動程式碼產生的比較
透過下列兩種方式,可以將 .NET Framework 組件 (Assembly) 中的 MSIL 編譯為機器碼:
手動編譯:可以使用原生映像產生器 (NGen.exe) 工具來建立原生映像。
自動編譯:Common Language Runtime (CLR) 會在執行階段執行 Just-in-Time (JIT) 編譯。
NGen.exe 和 JIT 編譯器都會提供控制程式碼產生的旗標。
載入組件時,CLR 會尋找組件的原生映像。 如果找不到具有正確程式碼產生旗標集的原生映像,CLR 便會在必要時執行 JIT 編譯來編譯組件中的函式。 即使已找到並載入原生映像,CLR 可能也會執行 JIT 編譯來編譯組件中的某些函式。
分析工具對程式碼產生的控制
分析工具會使用下表中的旗標控制程式碼產生。
旗標 |
作用 |
---|---|
COR_PRF_USE_PROFILE_IMAGES |
(需要 .NET Framework 2.0 版)讓原生映像搜尋功能尋找分析工具增強型的映像 (ngen /profile)。 如果該搜尋功能在指定的組件中找不到分析工具增強型原生映像,CLR 將在必要時改用 JIT 編譯來編譯該組件中的方法。 對經過 JIT 編譯的程式碼沒有效果。 |
COR_PRF_DISABLE_INLINING |
對原生映像搜尋功能沒有效果。 在 JIT 編譯時停用內嵌功能, 而所有其他最佳化項目則維持為作用中。 |
COR_PRF_DISABLE_OPTIMIZATIONS |
對原生映像搜尋功能沒有效果。 在 JIT 編譯時停用所有最佳化項目,包括內嵌功能。 |
COR_PRF_MONITOR_ENTERLEAVE |
讓原生映像搜尋功能尋找分析工具增強型的映像 (ngen /profile)。 在 JIT 編譯時,將 Enter/Leave 攔截程序 (Hook) 插入產生的程式碼中。 |
COR_PRF_MONITOR_CODE_TRANSITIONS |
讓原生映像搜尋功能尋找分析工具增強型的映像 (ngen /profile)。 在 JIT 編譯時,於 Managed/Unmanaged 轉換點插入攔截程序。 |
分析工具與原生映像
當 NGen.exe 建立原生映像時,會執行 CLR 一般在執行階段執行之工作 (例如,載入類別和編譯函式) 的大部分內容。 因此,在使用 NGen 完成工作時,執行階段期間將不會接收下列分析工具回呼:
分析工具增強型原生映像
使用 NGen.exe 建立原生映像會開啟一組程式碼產生旗標,這些旗標會使映像更容易進行分析,如下所示:
會將 Enter/Leave 攔截程序插入程式碼中。
會將 Managed/Unmanaged 轉換攔截程序插入程式碼中。
第一次叫用原生映像中的每個函式時,就會發出 ICorProfilerCallback::JITCachedFunctionSearchStarted 和 ICorProfilerCallback::JITCachedFunctionSearchFinished 告知。
第一次使用原生映像中的每個類別時,就會發出 ICorProfilerCallback::ClassLoadStarted 和 ICorProfilerCallback::ClassLoadFinished 告知。
效能考量
用來分析 NGen 所產生之應用程式的方法,會取決於下列兩個考量:您需要取得的資料,以及應用程式上內嵌分析攔截程序的效用。
如稍早在本主題中所討論,有兩個基本 NGen 分析案例:
一般原生映像 (NGen 產生的映像,但沒有分析攔截程序):這些映像不會導致分析負荷。 不過,類別載入/卸載回呼無法用於一般原生映像。 若要處理這個狀況,不想要求分析工具增強型原生映像的分析工具在發現 ID 時,將需要收集 FunctionID 或 ClassID 的相關資料。 例如,因為沒有對一般 NGen 產生的映像發出類別載入/卸載回呼,所以當 FunctionID 首次經過 JIT 編譯或從 NGen 產生的映像中載入時,取樣分析工具將不會發現 FunctionID。 當範例顯示出已在函式之已編譯程式碼主體內部的指令指標 (IP) 中執行處理序時,分析工具稍後會發現 FunctionID。 在這個情況下,分析工具會在取樣期間查詢函式的相關資訊,或者記錄 FunctionID 或相關聯的中繼資料語彙基元,以便在之後進行查詢。 因此,第一次產生 ID 時,分析工具只會在最後可能的時刻 (偵測到實際上使用 ID 時) 查詢 FunctionID 或 ClassID 的相關資訊,而不是較早時查詢。
分析工具增強型原生映像 (NGen 產生的映像,其中具有內嵌式分析攔截程序):這些映像較大,而且與一般映像有顯著的差別。 此外,應用程式中包含分析工具攔截程序時,其行為可能有所不同。 因此,您應該只在可接受潛在效能和行為後果 (負荷) 時,才使用分析工具增強型原生映像。