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

JIT编译的代码驻留在哪里?

龙涵蓄
2023-03-14

所以我有一个用Java编写的方法:

public void myMethod(int y){
    int x = 5 + y;
    doSomething(x);
}

假设我的应用程序调用了很多次...

在Java虚拟机上运行该方法的编译代码时,JVM将首先解释该方法。然后一段时间后,如果我理解正确,它将决定将其编译为机器语言。

此时,

它会被内存中的机器代码覆盖吗?如果被覆盖,大小差异问题将如何解决?如果将其写入内存中的其他位置,加载到内存中的字节码是否会被释放?而且,如果字节码和jit编译的代码都在内存中,当应用程序再次点击此方法时,JVM如何决定执行jit编译的代码而不是字节码?

共有3个答案

龙俊德
2023-03-14

据我所知,Java®虚拟机规范没有规定任何这些<我能找到的关于JIT的唯一参考是第3章:

[...]这种翻译器的一个例子是即时(JIT)代码生成器,它仅在加载虚拟机代码后生成Java特定于平台的指令。本章不涉及与代码生成相关的问题,仅涉及与编译用Java编程语言编写的源代码以Java虚拟机指令相关的问题。

所以据我所知,这可以通过不同的实现来实现。

然而,在我看来,包含java字节码的内存不太可能被本机CPU指令覆盖,因为CPU指令在技术上是可执行的,字节码只是数据,因为它必须被解释。但这并非不可能,只是很奇怪。

谭灿
2023-03-14

不,它不会被覆盖,因为两个表示在同一个位置通常没有实际的好处。JVM字节码只是一段数据。JIT发出的代码是本机CPU指令流(在某些体系结构中,需要将其显式标记为可执行)。

通常,当需要执行新函数时,即时编译器读取该函数的字节码,在其他地方分配内存,将等效的本机代码写入该内存,然后返回指向新生成的本机代码条目的函数指针。

邹博明
2023-03-14

HotSpot JVM在Metaspace(或早期版本中的PermGen)中有一个方法结构。它包含从不被覆盖的方法字节码和指向已编译代码的指针,在方法编译之前,该指针最初为NULL。

一个方法可能有多个入口点:

  • <代码>\u i2i\u条目-指向字节码解释器的指针
  • <代码>\u代码-

编译后的方法可能有不常见的陷阱,在某些罕见的情况下会回退到解释器。此外,Java方法可以多次动态重新编译,因此JVM不能丢弃原始字节码。无论如何,释放它是没有意义的,因为字节码通常比编译后的代码小得多。

 类似资料:
  • 问题内容: 所以我有用Java编写的这种方法: 并假设我的应用程序多次调用此方法。 在Java虚拟机上为该方法运行编译后的代码时,JVM将首先解释该方法。然后经过一段时间,如果我理解正确,它将决定将其编译为机器语言。 这一点, 会被内存中的机器代码覆盖吗?如果覆盖,大小差异问题将如何解决?如果将其写入内存中的其他位置,加载到内存中的字节码是否会释放?而且,如果字节代码和jit编译代码都在内存中,那

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

  • 问题内容: 我正在寻找Sun标准Java编译器的源代码。 jdk1.6.0_07有一些相关的类,但它们是接口(和)。在和下还有一些包,它们似乎是表示Java抽象语法树的接口。 但是我找不到编译器源-有人知道它在哪里吗? 问题答案: 检查此站点Java编程语言编译器(javac)组。来源在Mercurial存储库中。 jdk7 / tl / langtools(对于JDK 1.7) jdk6 / j

  • 问题内容: 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

  • 这个问题与android系统有关。Dalvik VM使用JIT概念,这意味着当您第一次运行应用程序时,Dalvik VM编译它并加载到RAM中,只要它能留在那里。我理解这个概念。而新的称为ART的虚拟机则使用AOT方法。ART编译应用程序后,你安装它(或当你正在安装它?)。这意味着什么?ART编译的应用程序与已编译的应用程序(如C应用程序)相同,但运行在与其他操作系统分离的独立进程中?谁能更透彻地