即时编译 - 它何时实际发生在Java中?

3ya*_*uya 6 java performance jit

最近我参加了关于Java效率的讨论.正如我所听到的,反对Java的大量论据是解释"非常耗时",因为它甚至简单的Java程序运行速度比直接编译到机器代码的类似程序慢.

答案就是Java代码经常直接编译为机器代码,如果只有JVM计算它会使程序比以标准方式解释更快.

我的问题是:JVM何时"决定"执行即时编译?使JIT比标准字节码解释更有效的标准是什么?我的意思是,编译本身需要一些时间,据我所知,当程序已经运行时,它应该发生了吗?

Lou*_*man 10

这取决于您的JVM及其设置.维基百科:

例如,Sun的Java虚拟机有两种主要模式 - 客户端和服务器.在客户端模式下,执行最少的编译和优化,以减少启动时间.在服务器模式下,执行大量编译和优化,以便在应用程序运行时通过牺牲启动时间来最大限度地提高性能.其他Java即时编译器使用运行时测量方法执行的次数与方法的字节码大小相结合作为启发式来决定何时编译.[4] 还有一个使用与循环检测结合执行的次数.[5]

对于vanilla HotSpot JVM in -server模式的粗略近似是当JVM注意到某个方法已被大量调用时,通常会超过某些特定次数,从而发生JIT.(这就是为什么JVM被称为"HotSpot" - 因为它识别并优化代码中的"热点".)此时,JVM知道一些事情:

  • 它知道这种方法值得花时间进行优化,因为它会被大量调用.
  • 它对这个函数的真实世界特征了解很多:
    • 如果一个if语句的一个分支比另一个分支更常见,那么它可以改进 分支预测
    • 如果List传递给这个方法通常是一个ArrayList,那么它可以对一个特定的情况进行优化和内联ArrayList.

请注意,如果您事先编译为机器代码,则不会有大量此类信息需要优化 - 编译器事先并不知道哪些路径比其他路径更常见.但是,如果您等到实际数据之后再进行优化,则可以做出更好的优化决策.

关于JIT做什么的更多细节在这里.

  • 那是......有点准确.在某些方面,Java可以比预编译的机器代码更快_faster_,因为它更了解代码的运行时特性,但Java可能比其他语言更慢,以便"热身"代码中的热点. (3认同)