当前位置: 首页 > 面试题库 >

JVM如何决定JIT编译方法(将方法分类为“hot”)?

何兴安
2023-03-14
问题内容

我已经使用-XX:+PrintCompilation,并且我知道JIT编译器的基本技术以及为什么使用JIT编译。

但是我仍然没有找到JVM如何决定JIT编译方法的方法,即“何时到了JIT编译方法的正确时间”。

我假设每个方法都开始被解释,并且只要它不被归类为“热方法”,就不会被编译,这是对的吗?我脑海里有些东西我读到,当一个方法执行至少10.000次(解释该方法10.000次后,将被编译)时,该方法被视为“热”,但我必须承认不知道这个或我在哪里读过。

所以总结一下我的问题:

(1)是否对每种方法都进行了解释,只要它没有被归类为“热”方法(因此已经被编译),或者即使没有“热”方法也有理由进行编译吗?

(2)JVM如何将方法分为“非热”和“热”方法?执行次数?还要别的吗?

(3)如果“热”方法有某些阈值(如执行次数),是否有Java标志(-XX:...)设置该阈值?


问题答案:

HotSpot编译策略相当复杂,尤其是对于分层编译而言,它在Java 8中是默认启用的。它既不是执行次数,也不是CompileThreshold参数。

最佳解释(显然是唯一合理的解释)可以在HotSpot源中找到,请参阅advancedThresholdPolicy.hpp。

我将总结此高级编译策略的要点:

  • 执行从第0层(解释器)开始。
  • 编译的主要触发因素是
  • 方法调用计数器i;
  • 后柜台b。向后分支通常表示代码中的循环。
  • 每次计数器达到一定的频率值(TierXInvokeNotifyFreqLog,TierXBackedgeNotifyFreqLog),编译政策被称为决定下一步与当前正在运行的方法做什么。取决于的值i,b而C1和C2的编译器线程的当前负载,可以决定

  • 继续在解释器中执行;

  • 开始分析翻译;
  • 在第3层使用C1编译方法,并提供进一步重新编译所需的完整html" target="_blank">配置文件数据;
  • C1在第2层的编译方法,没有概要文件,但有可能重新编译(不太可能);
  • 最后在没有配置文件或计数器的第1层使用C1编译方法(也不可能)。
    这里的关键参数是TierXInvocationThresholdTierXBackEdgeThreshold。可以根据编译队列的长度为给定方法动态调整阈值。

  • 编译队列不是FIFO,而是优先级队列。

  • 具有概要数据(第3层)的C1编译代码的行为类似,不同之处在于切换到下一个级别(C2,第4层)的阈值要大得多。例如,大约200次调用后,解释的方法可以在第3层进行编译,而经过5000次调用后,C1编译的方法将在第4层进行重新编译。

  • 特殊策略用于方法内联。即使它们不是“热”的,它们也可以内联到调用方中。只有频繁调用()时InlineFrequencyRatio,才可以内联更大的方法InlineFrequencyCount



 类似资料:
  • 我已经使用过,我知道JIT-compiler的基本技术以及为什么要使用JIT-compilization。 然而,我仍然没有发现JVM是如何决定JIT编译一个方法的,即“当合适的时间来JIT编译一个方法时”。 我假设每个方法都开始被解释,只要它不被归类为“热方法”,它就不会被编译,这是对的吗?我在后脑勺上读到,当一个方法被执行至少10.000次(在解释该方法10.000次后,它将被编译)时,它被认

  • 我已经使用过,并且我知道JIT-编译器的基本技术以及为什么使用JIT-编译。 然而,我仍然没有发现JVM是如何决定JIT编译一个方法的,即“当正确的时间到来时JIT编译一个方法”。 (2)JVM如何将方法分为“非热”和“热”方法?执行次数?还要别的什么吗? (3)如果“hot”方法有特定的阈值(如执行次数),是否有Java标志()来设置此阈值?

  • 问题内容: 我的Java应用程序出现问题,JIT破坏了代码。如果禁用JIT,一切正常,但运行速度慢10-20倍。 有什么方法可以禁用特定方法或类的JIT吗? 编辑:我正在使用Ubuntu 10.10,得到相同的结果都与: 和: 问题答案: 以下选项适用于我的JVM,以排除特定方法:

  • 问题内容: 我正在尝试为我的简单类生成hashCode()方法,但是我什么也没用。我将不胜感激任何帮助。我已经实现了equals()方法,该方法如下所示,并且还想知道是否需要实现compareTo()方法。我已经导入了java.lang.Character以使用character.hashCode(),但它似乎不起作用。 提前致谢… 正在给我java.lang.Comparable转换错误的com

  • 问题内容: 有什么方法可以查看JIT在JVM中生成的本机代码吗? 问题答案: 假设你使用的是Sun Hotspot JVM(即Oracle 在java.com上提供的JVM ),则可以添加该标志 在运行代码时。这将打印出由JIT编译器生成的优化代码,而将其余部分省去。 如果要查看整个字节码,包括未优化的部分,请添加

  • 我知道这依赖于JVM,每个虚拟机都会选择实现它,但我想了解总体概念。 据说对于JVM用来执行Java程序的内存段 Java堆栈 不一定用连续内存实现,并且可能都实际分配在操作系统提供的一些堆内存上,这就引出了我的问题。 完全使用JIT机制并将字节码方法编译为本机机器码方法的JVM将这些方法存储在某个地方,那会在哪里?执行引擎(通常用C/C编写)将不得不调用这些JIT编译函数,然而内核不应该允许程序