CLR vs JIT

JIT编译器和CLR有什么区别? 如果你编译你的代码到CLR并运行这个代码,那么JIT在做什么? JIT编译如何随着generics向CLR的添加而改变?

JIT是CLR的一个方面。

具体来说,它是负责将由原始语言的编译器(例如,用于Microsoft C#的csc.exe)产生的CIL / MSIL(以下称为IL)更改为当前处理器本地的机器代码(以及它在当前进程中公开的体系结构,例如32 / 64bit)。 如果有问题的程序集没有被使用,那么JIT过程是完全不必要的,CLR将会运行这个代码,没有它。

在使用尚未从中间表示转换的方法之前,JIT有责任将其转换。
准确地说, 何时 JIT将执行具体实施,并且可能会有变化。 然而,CLRdevise要求JIT 相关的代码执行之前发生,与此相反,JVM可以自由地解释代码一段时间,而单独的线程创build一个机器代码表示。
“正常的”CLR使用JIT之前的存根方法 ,其方法是仅在使用JIT时进行编译。 这涉及使初始本地方法存根是间接指示JIT编译方法,然后修改原始调用以跳过初始存根。 当前的紧凑版本,而是加载时编译一个types的所有方法。

解决generics的问题。

这是对IL规范和JIT语义的最后一个重大改变,而不是其内部的实现细节。

添加了几个新的IL指令,为仪表types和成员提供了更多的元数据选项。 在IL级别也添加了限制条件。

当JIT编译一个具有generics参数的方法(显式或隐式地通过包含类)时,它可以为每个使用的types设置不同的代码path(机器代码指令)。 在实践中,JIT使用所有引用types的共享实现,因为这些variables将显示相同的语义并占用相同的空间(IntPtr.Size)。

每个值types将得到为其生成的特定代码,处理堆栈/堆中variables的减小/增加的大小是造成这种情况的主要原因。 另外,通过在方法调用之前发出约束操作码,许多对非引用types的调用不需要将值调出​​方法(该优化也用于非通用情况)。 这也允许默认的<T>行为被正确地处理,并且当使用非Nullable值types时,用于将null比较为无操作(总是为假)。

如果在运行时尝试通过reflection来创buildgenericstypes的实例,那么types参数将由运行时validation,以确保它们传递任何约束。 这不会直接影响JIT,除非在types系统中使用(尽pipe不太可能)。

你将你的代码编译成IL,然后在运行时将它们编译成机器代码,这就是所谓的JIT。

编辑 ,多出一些答案(仍然过于简化):

当你在Visual Studio中编译你的C#代码时,它变成了CLR理解的IL,对于运行在CLR之上的所有语言,IL是相同的(这使得.NET运行时能够使用多种语言和内部操作他们之间轻松)。

在运行期间,IL被解释为机器代码(特定于您所在的架构),然后执行。 这个过程叫做即时编译或简称JIT。 只有需要的IL被转换成机器代码(并且只有一次,一旦它被编译成机器码,它就被“caching”), 只是在执行之前,因此被命名为JIT。

这就是C#的样子

C#代码> C#编译器> IL > .NET运行时> JIT编译器>机器码>执行

这就是VB的样子

VB代码> VB编译器> IL > .NET运行时> JIT编译器>机器码>执行

正如你所看到的,只有两个第一步对于每种语言都是独一无二的,并且在它变成IL之后的所有东西都是一样的,就像我之前说的那样,你可以在.NET之上运行几种不同的语言

正如Jon Skeet所说,JIT是CLR的一部分。 基本上这是在引擎盖下发生的事情:

  1. 您的源代码被编译成一个称为通用中间语言(CIL)的字节码。
  2. 来自每个类和每个方法(以及其他所有事物:O)的元数据包含在生成的可执行文件的PE标头中(无论是dll还是exe)。
  3. 如果您正在生成可执行文件,那么PE头文件还包含一个传统的引导程序,当您执行可执行程序时,该程序负责加载CLR(公共语言运行库)。

现在,当你执行:

  1. 引导程序初始化CLR(主要通过加载mscorlib程序集)并指示它执行程序集。
  2. CLR执行您的主要条目。
  3. 现在,类有一个向量表,它保存着方法函数的地址,所以当你调用MyMethod时,这个表被search,然后进行相应的地址调用。 在开始时,所有表的所有条目都具有JIT编译器的地址。
  4. 当对这种方法之一进行调用时,调用JIT而不是实际的方法并进行控制。 然后,JIT将CIL代码编译为合适的体系结构的实际汇编代码。
  5. 一旦代码被编译,JIT进入方法向量表, 并用编译后的代码replace地址,以便每个后续调用不再调用JIT。
  6. 最后,JIT处理执行到编译的代码。
  7. 如果你调用另一个尚未编译的方法,则返回到4 …等等。

JIT基本上是CLR的一部分 。 垃圾收集器是另一个。 相当你把互操作的责任等等是另一回事,而我是非常不合格的评论:)

我知道这个线程很老,但我想我可能会把这个让我理解JIT的图片放进去。 这是来自Jeffrey Ritcher通过C#编写的优秀书CLR 。 在图片中,他正在讨论的元数据是在汇编头中发布的元数据,其中存储了有关程序集中types的所有信息:

从CLR的JIT图像通过C#

1)在编译.net程序时.net程序代码被转换成中间语言(IL)代码

2)在执行程序时,中间语言代码在调用方法时被转换为操作系统本地代码; 这就是所谓的JIT(Just in Time)编译。

  1. Common Language Runtime(CLR)是解释器,而Just In Time(JIT)是.Net Framework中的编译器。

2.JIT是.NET的内部编译器,它从CLR获取MicroSoft中间代码语言(MSICL)代码,并执行它来处理特定的指令,而CLR作为引擎工作,其主要任务是向MS提供MSICL代码以确保代码根据机器规格完全编译。