当前位置: 首页 > 知识库问答 >
问题:

JVM中的JIT编译器到底是什么?

公孙胡媚
2023-03-14

我试图理解Java源代码是如何执行的,我对JVM中的JIT编译器究竟是什么感到困惑。首先,让我告诉您我是如何理解从Java源代码到在计算机上执行机器代码的过程的。也许,我在这一过程中误解了一些导致混淆的东西。

步骤如下:

  1. 源代码被编译成字节码(.class文件)

现在,根据维基百科关于JVM的文章,更具体地说是“字节码解释器和实时编译器”部分,为了执行Java字节码,您需要一个解释器(但我们有一个JIT编译器)。

现在有一点让我困惑。我把它分解成引号:

当Java字节码由解释器执行时,执行速度总是比编译成本机语言的同一程序的执行速度慢

>

  • 由于计算机只能执行机器代码,并且解释器将字节码转换为机器代码的速度比编译器慢,为什么JVM使用解释器而不是编译器?

    为什么我们没有JIT编译器为CPU生成的另一个中间可执行文件,以便它可以快速执行指令

    “JIT编译器可以在执行程序时将Java字节码翻译成本机语言。然后,程序的翻译部分可以比它们可以被解释的速度快得多。这种技术可以应用于程序中经常执行的部分。”

    即时编译器真的是能够编译经常执行的代码的解释器吗?编译器和解释器这两个术语是否错误地互换使用?

    提前谢谢。

  • 共有2个答案

    昌栋
    2023-03-14

    由于计算机只能执行机器代码,并且解释器将字节码转换为机器代码的速度比编译器慢,为什么JVM使用解释器而不是编译器?

    优化编译是一个非常持久的过程。只有当程序运行更长时间时,这笔费用才是合理的。

    不需要在错误的位置进行优化。一段只遍历一次的代码将消耗比解释时间更多的编译时间,因此解释是可以的。

    如果频繁处理代码的某些部分,编译器会跳进来更好地处理这两个主题。

    为什么我们没有JIT编译器为CPU生成的另一个中间可执行文件,以便它可以快速执行指令?

    这个“文件”(编译后的片段)确实存在于内存中。它没有序列化为文件,因为:

    • 这样的文件在很大程度上依赖于操作系统和硬件
    • 有些代码优化只能在运行时应用,例如JIT编译器可以优化虚拟调用(用跳转甚至内联代码代替动态调度)

    即时编译器真的是一个具有编译能力的解释器吗

    虽然JVM热点编译器编译频繁执行的代码,但其他JIT编译器可能会根据其他启发式方法决定编译。术语“JIT编译器”和“解释器”没有明确区分。大多数解释器进行优化(及时编译),几乎每个JIT编译器都进行解释器。

    廉展鹏
    2023-03-14

    由于计算机只能执行机器代码,并且解释器将字节码转换为机器代码的速度比编译器慢,为什么JVM使用解释器而不是编译器?

    因为编译到机器代码也需要时间,特别是当它必须分析代码以优化代码时,所以解释速度足够快,可以在大多数时间执行,如果只偶尔运行一次,实际上比编译运行快。

    此外,解释器不会“将字节码转换为机器码”。它评估字节码并执行字节码请求的操作。解释器本身是机器代码,但它不翻译字节码,而是解释/计算字节码。

    为什么我们没有JIT编译器为CPU生成的另一个中间可执行文件,以便它可以快速执行指令?

    这将违反Java的一次编写,随处运行范式。

    即时编译器真的是一个能够编译经常执行的代码的解释器吗?

    不,JIT编译器(或者更准确地说,EJP提到的热点编译器)是由JVM根据需要执行的编译器。

    编译器和解释器这两个术语是否被错误地互换使用?

    对的它们不能互换使用,因为它们的作用不同。解释器执行字节码。JIT/HotSpot编译器将字节码转换为机器码,但不运行它。

     类似资料:
    • 请注意,我的问题是关于JVM解释器,而不是JIT编译器。JIT编译器将java字节码转换为本机代码。因此,这必须意味着JVM中的解释器不会将字节码转换为机器码。因此,问题是:从本质上讲,口译员做什么?如果有人能帮我用一个简单的字节码示例来回答这个问题,相当于1 1=2,即解释器在执行这个加法操作时做了什么?(我的隐含问题是,如果解释器不翻译为机器代码,那么哪个CPU执行添加操作,那么该操作是如何执

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

    • 问题内容: Sun的规范JVM实现对字节码进行了一些相当复杂的优化,以在代码运行几次后获得接近本机的执行速度。 问题是,为什么没有将此编译后的代码缓存到磁盘以供以后使用同一功能/类时使用? 就目前而言,每次执行程序时,JIT编译器都会重新启动,而不是使用代码的预编译版本。当本质上解释字节码时,是否添加此功能不会大大提高程序的初始运行时间? 问题答案: 我不求助于@MYYN发布的链接的’n’past

    • 主要内容:JIT编译器语法,JIT编译器的风险和假设JIT 编译器是用 C++ 编写的,用于将 Java 转换为字节码。现在 Java 10 可以选择启用基于 Java 的实验性 JIT 编译器 Graal 来代替标准的 JIT 编译器。Graal 正在使用 Java 9 中引入的 JVMCI,即 JVM 编译器接口。 Graal 在 Java 9 中也可用。使用 Java 10,我们可以启用 Graal 来测试和调试实验性 JVM 编译器。 JI

    • 问题内容: 我经常碰到声称Java被解释的文章。我知道Oracle的HotSpot JRE提供即时编译,但是大多数台式机用户都是这种情况吗?例如,如果我通过http://www.java.com/en/download下载Java ,它将包括JIT编译器吗? 问题答案: 是的,一点没错。声称Java被解释的文章通常由不了解Java的工作原理或不了解解释的含义的人撰写。 话虽如此,HotSpot 有

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