Java和.Net在JIT中有什么区别
我知道Microsoft .NET使用CLR作为JIT编译器,而Java有Hotspot。它们之间有什么区别?
我知道Microsoft .NET使用CLR作为JIT编译器,而Java有Hotspot。它们之间有什么区别?
他们是截然不同的野兽。正如人们所指出的,CLR在执行MSIL之前编译为机器代码。除了典型的死代码消除和内联私有优化之外,这还允许它利用目标计算机的特定CPU架构(尽管我不确定它是否这样做)。这也会导致每个类受到冲击(尽管编译器相当快,并且许多平台库只是Win32 API上的一个薄层)。
HotSpot VM 正在采用不同的方法。它规定大多数代码很少执行,因此不值得花时间编译它。所有字节码都以解释模式启动。VM 在调用站点保留统计信息,并尝试识别调用次数超过预定义次数的方法。然后,它仅使用快速JIT编译器(C1)编译这些方法,并在运行时交换该方法(这是HS的特殊酱汁)。在 C1 编译的方法被调用更多次后,将使用缓慢但复杂的编译器编译相同的方法,并且代码将再次动态交换。
由于 HotSpot 可以在方法运行时交换方法,因此 VM 编译器可以执行一些在静态编译代码中不安全的推理优化。一个规范的例子是单态调用的静态调度/内联(只有一个实现的多态方法)。如果 VM 看到此方法始终解析为同一目标,则执行此操作。过去复杂的调用被简化为几个CPU指令保护,这些指令由现代CPU预测和流水线。当保护条件停止为 true 时,VM 可以采用不同的代码路径,甚至回退到解释模式。根据统计数据和程序工作量,生成的机器代码在不同时间可能会有所不同。其中许多优化依赖于在程序执行期间收集的信息,如果编译一旦加载类,则不可能实现。
这就是为什么在对算法进行基准测试时需要预热 JVM 并模拟实际工作负载的原因(倾斜的数据可能会导致对优化的不切实际的评估)。其他优化包括锁免、自适应自旋锁定、逃逸分析和堆栈分配等。
也就是说,HotSpot只是其中一个虚拟机,JRockit,Azul,IBM的J9和Resettable RVM,它们都具有不同的性能配置文件。