Bagikan melalui


Pengoptimalan dan Penelusuran Kesalahan JIT

Jika Anda mencoba mendebug kode, akan lebih mudah bila kode tersebut TIDAK dioptimalkan. Ketika kode dioptimalkan, kompiler dan runtime membuat perubahan pada kode CPU yang dipancarkan sehingga berjalan lebih cepat, tetapi memiliki pemetaan yang kurang langsung ke kode sumber asli. Jika pemetaannya kurang langsung, debugger sering kali tidak dapat memberi tahu Anda nilai variabel lokal, dan langkah kode serta titik henti sementara mungkin tidak berfungsi seperti yang Anda harapkan.

Catatan

Untuk info lebih lanjut tentang penelusuran kesalahan JIT (Just In Time), baca dokumentasi ini.

Cara kerja pengoptimalan di .NET

Biasanya konfigurasi build Rilis membuat kode yang dioptimalkan dan konfigurasi build Debug tidak. Properti MSBuild Optimize mengontrol apakah kompiler diberitahu untuk mengoptimalkan kode.

Dalam ekosistem .NET, kode diubah dari sumber ke instruksi CPU dalam proses dua langkah: pertama, kompiler C# mengonversi teks yang Anda ketikkan ke bentuk biner perantara yang disebut MSIL dan menulis MSIL ke file .dll. Kemudian, .NET Runtime mengonversi instruksi MSIL ini ke CPU. Kedua langkah dapat mengoptimalkan sampai tingkat tertentu, tetapi langkah kedua yang dilakukan oleh .NET Runtime melakukan pengoptimalan yang lebih signifikan.

Opsi 'Tekan pengoptimalan JIT pada pemuatan modul (Hanya terkelola)'

Debugger mengekspos opsi yang mengontrol apa yang terjadi ketika DLL yang dikompilasi dengan pengoptimalan yang diaktifkan dimuat di dalam proses target. Jika opsi ini tidak dicentang (status default), kemudian ketika .NET Runtime mengkompilasi kode MSIL ke dalam kode CPU, pengoptimalan akan diaktifkan. Jika opsi dicentang, debugger meminta agar pengoptimalan dinonaktifkan.

Untuk menemukan opsi Tekan pengoptimalan JIT pada pemuatan modul (Hanya terkelola), pilih Alat>Opsi, lalu pilih Umum halaman di bawah node Penelusuran Kesalahan.

Menekan Pengoptimalan JIT

Kapan sebaiknya Anda mencentang opsi 'Tekan pengoptimalan JIT'?

Centang opsi ini saat Anda mengunduh DLL dari sumber lain, seperti paket nuget, dan Anda ingin mendebug kode di DLL ini. Agar tekanan berfungsi, Anda juga harus menemukan file simbol (.pdb) untuk DLL ini.

Jika Anda hanya tertarik untuk penelusuran kesalahan kode yang Anda buat secara lokal, sebaiknya biarkan opsi ini tidak dicentang, karena, dalam beberapa kasus, mengaktifkan opsi ini akan memperlambat proses penelusuran kesalahan secara signifikan. Ada dua alasan untuk perlambatan ini:

  • Kode yang dioptimalkan berjalan lebih cepat. Jika Anda menonaktifkan pengoptimalan untuk banyak kode, dampak performa dapat bertambah.
  • Jika Anda mengaktifkan Hanya Kode Saya, debugger bahkan tidak akan mencoba memuat simbol untuk DLL yang dioptimalkan. Menemukan simbol bisa memakan waktu lama.

Batasan opsi 'Tekan optimasi JIT'

Ada dua situasi di mana mengaktifkan opsi ini TIDAK akan berfungsi:

  1. Dalam situasi di mana Anda melampirkan debugger ke proses yang sudah berjalan, opsi ini tidak akan berpengaruh pada modul yang sudah dimuat pada saat debugger dilampirkan.

  2. Opsi ini tidak berpengaruh pada DLL yang telah dikompilasi sebelumnya (atau ngen'ed) ke kode asli. Namun, Anda dapat menonaktifkan penggunaan kode yang telah dikompilasi sebelumnya dengan memulai proses dengan variabel lingkungan 'COMPlus_ReadyToRun' diatur ke '0'. Ini akan memberi tahu runtime .NET Core untuk menonaktifkan penggunaan gambar yang telah dikompilasi sebelumnya, memaksa runtime untuk mengkompilasi kode kerangka kerja JIT.

    Jika Anda menargetkan .NET Framework, tambahkan variabel lingkungan 'COMPlus_ZapDisable' dan atur ke '1'.

Atur "COMPlus_ReadyToRun": "0" dengan menambahkannya ke setiap profil di file Properties\launchSettings.json:

{
  "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"
    }
  }
}