【问题标题】:Where does the JIT compiled code reside?JIT 编译的代码在哪里?
【发布时间】:2015-03-23 10:43:46
【问题描述】:

所以我有这个方法,用Java写的:

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

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

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

此时,

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

【问题讨论】:

  • 我的想法是,这种事情取决于您是在 Windows 机器上运行,还是在内存不足的微控制器上运行。换句话说,取决于平台,不是吗?
  • 答案 1:你为什么在乎?答案 2:JVM 将每个方法的 JITCed 代码保存在 C 堆中,通过类对象的内部表示中的表链接到。仅当 JVM 结束或在极少数情况下“卸载”类时才会删除代码。这一切都由适当的魔法管理。
  • “C 堆”在这里确实是用词不当——如果它指的是使用调用 malloc 获得的内存(可能是页对齐的,也可能不是页对齐的),则必须将相应的页标记为可执行.更有可能的是,JIT 使用 mmap、VirtualAlloc 等为生成的代码分配内存。
  • @MartinTörnwall - “C 堆”是 JVM 内部堆的通用术语,它不是 GC 堆的一部分。至于它是如何实现的,这取决于它运行的操作系统(还有许多其他环境超出你的想象)。
  • @HotLicks 啊你为什么在乎这个家伙在这里......你好!

标签: java jvm jit


【解决方案1】:

HotSpot JVM 在 Metaspace(或早期版本中的 PermGen)中有一个 Method 结构。 它包含永远不会被覆盖的方法字节码和a pointer to compiled code,在编译方法之前最初为NULL。

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

  • _i2i_entry - 指向字节码解释器的指针。
  • _code->entry_point() - JIT 编译代码的入口点。编译后的方法驻留在CodeCache - 本机内存的特殊区域,用于 VM 动态生成的代码。
  • i2cc2i 适配器从解释器调用编译后的代码,反之亦然。需要这些适配器,因为解释方法和编译方法具有不同的调用约定(参数传递方式、帧构造方式等)

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

【讨论】:

    【解决方案2】:

    不,它没有被覆盖,因为两个表示在同一个地方通常没有实际好处。 JVM 字节码只是一段数据。 JIT 发出的代码是原生 CPU 指令流(在某些架构中,需要明确标记为可执行)。

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

    【讨论】:

    • 另外:在许多现代平台上,您必须明确地从虚拟内存子系统请求可执行内存。没有充分的理由将字节码分配给可执行页面。
    【解决方案3】:

    据我所知,The Java® Virtual Machine Specification 没有指定任何内容。
    我能找到的对 JIT 的唯一引用是在Chapter 3

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

    所以据我了解,这可以通过不同的实现以不同的方式完成。

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

    【讨论】:

      猜你喜欢
      • 2011-03-18
      • 2014-07-20
      • 2015-09-26
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多