首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于HotSpot JIT的混淆

关于HotSpot JIT的混淆
EN

Stack Overflow用户
提问于 2017-08-20 08:20:36
回答 1查看 610关注 0票数 4

例如,在method.When中运行10000次的循环(运行1000次),backedge_counter触发JIT编译。解释器继续执行。当它循环4000时,JIT编译就完成了。

我的问题是,如何通过解释器或执行本机代码来执行余数6000?或者直到下次调用此方法时才执行本机代码?当下一次调用此方法时会发生什么?

EN

回答 1

Stack Overflow用户

发布于 2017-08-20 09:58:25

让我们重申这个问题:

Java HotSpot编译器是否能够在执行过程中将方法从解释更改为编译?

我想可以的。

这个任务对引擎来说并不容易(几年前,我在开发一个名为的PalmOS手持设备编译器时,在这个领域积累了一些经验)。当发动机决定切换时,它至少必须考虑以下几点:

  • 程序柜台在哪里?在解释的代码中,它位于某个字节码从方法开始的偏移处,确切地知道接下来要执行哪个字节码。在优化的本机代码中,JVM字节码通常不会转换成孤立的机器指令块,而是相互依赖、重新排列顺序等等。因此,在切换时,可能没有完全对应于字节码程序计数器的本机指令地址。
  • 数据在哪里?解释器(可能)将所有内容保存在堆栈上,优化后的本机代码使用寄存器和堆栈分配的混合,这将在本机翻译中的不同位置有所不同。

所以我读了HotSpot白皮书。它没有明确地回答这个问题,但是在“去优化”下面有一个提示。在调试会话中动态加载或替换新类时,以前的优化(如内联)可能变得无效。

因此,Java必须能够动态地去优化(如果需要的话,还可以重新优化)以前优化过的热点,即使在为热点执行代码时也是如此。

这也是在编译代码和解释代码之间的切换,但情况正好相反。由于这是记录在案的HotSpot引擎的行为,我得出的结论是,在当前正在执行的方法调用中,从解释代码切换到编译代码是可能的。

编辑:

对于我所理解的问题的核心,我还不够清楚。

据我所知,有一种方法在循环10000次迭代,如下所示:

代码语言:javascript
复制
void loop() {
    for (int i=0; i<10000; i++) {
        // example loop body
        objects[i].doSomething();
    }
}

例如,经过4000次迭代之后,HotSpot编译器优化了该方法。然后会发生什么呢?

有两个方面,一个是琐碎的,一个是复杂的:

  • 最重要的一点是,循环中发生的调用(例如,doSomething())一旦可用,就会立即调用它们的编译版本。我在最初的回答中没有提到这一点,因为我认为这是理所当然的。
  • 复杂的方面是:当前运行的loop()执行会从i=4000的解释代码切换到编译的代码吗?这就是我所理解的OP的问题。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45779997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档