JIT 最佳化和偵錯
若您想偵錯程式碼,當該程式碼 不是 最佳化時,會比較容易。 最佳化程式碼時,編譯器和執行時間會變更所發出的 CPU 程式碼,使其執行得更快,但與原始原始程式碼的對應會較不直接。 如果對應較不直接,偵錯工具通常無法告訴您區域變數的值,而且程式碼逐步執行和中斷點可能無法如預期般運作。
注意
如需 JIT (Just In Time) 偵錯的詳細資訊,請參閱 這個文件。
.NET 中最佳化的運作方式
發行組建設定通常會建立最佳化的程式碼,而偵錯組建設定則不會。 Optimize
MSBuild 屬性會控制編譯器是否被告知要最佳化程式碼。
在 .NET 生態系統中,程式碼會在兩個步驟的流程中從來源轉換成 CPU 指示: 首先,C# 編譯器會將您輸入的文字轉換成稱為 MSIL 的中繼二進位格式,並將 MSIL 寫入 .DLL 檔案。 然後,.NET 執行階段會將此 MSIL 轉換為 CPU 指示。 這兩個步驟都可以最佳化到某種程度,但 .NET 執行階段所執行的第二個步驟會執行更顯著的最佳化。
[在模組負載上隱藏 JIT 最佳化 (僅限受控)] 選項
偵錯工具會公開一個選項,控制當啟用最佳化編譯的 DLL 在目標流程內載入時會發生什麼情況。 如果未核取此選項 (預設狀態),則當 .NET 執行階段將 MSIL 程式碼編譯為 CPU 程式碼時,它會保持最佳化的啟用狀態。 如果已核取此選項,偵錯工具會要求停用最佳化。
若要尋找 [在模組載入上隱藏 JIT 最佳化 (僅限受控)] 選項,請選取 [工具]>[選項],然後選取 [偵錯] 節點底下的 [一般] 頁面。
何時應該檢查 [隱藏 JIT 優化] 選項?
當您從另一個來源下載 DLL 時,請檢查此選項,例如 nuget 套件,且您會想偵錯此 DLL 中的程式碼。 若要讓隱藏運作,您也必須找到此 DLL 的符號 (.pdb) 檔案。
如果您只想在本機建置的程式碼進行偵錯,最好不要核取此選項,因為在某些情況下,啟用此選項會大幅降低偵錯速度。 偵錯速度降低的原因有兩個:
- 最佳化程式碼的執行速度較快。 如果您要關閉許多程式碼的最佳化,效能影響可能會疊加。
- 如果您已啟用 Just My Code,偵錯工具甚至不會嘗試載入已最佳化的 DLL 符號。 尋找符號可能需要很長的時間。
[隱藏 JIT 最佳化] 選項的限制
在兩種情況下,開啟此選項將 沒有 用:
在將偵錯工具附加至已在執行的流程的情況下,此選項不會影響附加偵錯工具時已載入的模組。
此選項不會影響已預先編譯 (或產生) 為機器碼的 DLL。 不過,您可以啟動將環境變數 'COMPlus_ReadyToRun' 設定為 '0' 的流程來停用預先編譯程式碼的使用。 這會告訴 .NET Core 執行階段停用使用預先編譯的映像,強制執行階段使用 JIT 編譯架構程式碼。
如果您要以 .NET Framework 為目標,請新增環境變數 'COMPlus_ZapDisable',並將它設定為 '1'。
將它新增至 Properties\launchSettings.json檔案中的每個設定檔,以設定"COMPlus_ReadyToRun": "0"
:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59694/",
"sslPort": 44320
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"COMPlus_ReadyToRun": "0"
}
},
"HttpLoggingSample": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"COMPlus_ReadyToRun": "0"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}