Java和.Net之间的JIT有什么不同

我知道Microsoft .NET使用CLR作为JIT编译器,而Java具有Hotspot。 它们之间有什么区别?

他们是非常不同的野兽。 正如人们所指出的那样,CLR在执行一段MSIL之前编译为机器代码。 这允许它除了典型的死代码消除和内联关闭私有优化以利用目标机器的特定CPU架构(虽然我不确定它是否这样做)。 这也引起了每个类的冲击(尽管编译器相当快,并且许多平台库只是Win32 API上的一个薄层)。

HotSpot VM采用了不同的方法。 它规定大多数代码很少执行,因此花时间编译它是不值得的。 所有字节码都以解释模式启动。 VM在呼叫站点保留统计信息,并尝试识别被调用超过预定义次数的方法。 然后它只使用快速JIT编译器(C1)编译这些方法,并在运行时交换方法(这是HS的特殊情况)。 在多次调用C1编译的方法之后,使用缓慢但复杂的编译器编译相同的方法,并且动态地再次交换代码。

由于HotSpot可以在运行时交换方法,因此VM编译器可以执行一些在静态编译代码中不安全的推测性优化。 一个典型的例子是单态调用的静态调度/内联(只有一个实现的多态方法)。 如果VM发现此方法始终解析为同一目标,则会执行此操作。 以前的复杂调用简化为少数CPU指令保护,由现代CPU预测和流水线化。 当保护条件停止为真时,VM可以采用不同的代码路径,甚至回退到解释模式。 根据统计和程序工作量,生成的机器代码可以在不同的时间不同。 其中许多优化依赖于在程序执行期间收集的信息,如果您在加载类时编译一次,则无法实现。

这就是为什么在对基准算法进行基准测试时需要预热JVM并模拟实际工作负载的原因(偏差数据会导致对优化的不切实际的评估)。 其他优化包括锁定省略,自适应自旋锁定,逃逸分析和堆栈分配等。

也就是说,HotSpot只是其中一个虚拟机。 JRockit,Azul,IBM的J9和Resettable RVM,都有不同的性能配置文件。