Когда вы нажимаете "зелёную кнопку" происходит следующее:
- Visual studio вызывает .NET SDK
- .NET SDK вызывает msbuild
- msbuild в определённый момент вызывает csc.exe (C# Compiler)
- csc.exe генерирует IL (aka MSIL, aka CIL) и заталкивает его в DLL-ки
- ^---- Это происходит при сборке проекта
- <-- В этот момент на .net framework можно было натравить Ngen и пропустить чать JIT-компиляции
- V---- А это при каждом запуске
- Затем .NET Runtime берёт эти сборки и передаёт IL-код JIT-компилятору
- Пока JIT в фоне компилирует IL в машинный код - рантайм интерпретирует IL
- Когда IL скомпилировался - рантайм берёт сгенерированный машинный код
- При этом в фоне JIT может собирать информацию о том, какие методы чаще вызываются, чтобы ещё их оптимизировать.
Ещё во время сборки проекта можно предварительно натравить JIT на код.
При запуске это позволит пропустить этап с интерпретацией и сразу запустить исполняемый код.
Эта фича называется
ReadyToRun Compilation
Тут в одном из ответов посоветовали CLR via C# - я считаю, что это уже не самая актуальная книга, тк в .NET Core многое поменялось / дополнилось и могут отличаться нюансы.
Если хотите подробнее узнать про JIT - начните с этого доклада:
https://www.youtube.com/watch?v=H1ksFnLjLoY