8

当 jvm(在我的例子中是热点)将某些代码路径永久编译为机器代码时,该机器代码存储在哪里?在进程内存的 .text 段中?在进程的堆中??

我不是在谈论 JITing。据我了解,JIT 将编译和运行字节码,而无需将编译后的代码保存在任何地方。但是当 jvm保存该代码时——它在进程空间中的哪个位置保存它呢? ...正如评论和答案所指出的,我所要求的一切实际上都是 JIT 的一部分。

编辑:

根据我在下面的评论,我特别提到的情况在这里记录为“自适应优化”:http ://www.oracle.com/technetwork/java/whitepaper-135217.html#hotspot

4

2 回答 2

3

首先,您所描述的是 JIT - 特别是它在 Hotspot 中的工作方式

要回答您关于代码在运行时保存在哪里的问题- 它位于进程堆中,并且对象的 Klass 文件中指向方法代码的指针已更新为指向它。还有一种称为 OSR(堆栈替换)的东西,用于直接在堆栈上编译长时间运行的循环。

于 2013-06-25T22:39:03.897 回答
3

我没有使用过生产质量的虚拟机,但这是我的 5 美分。

.textUnix 可执行文件中的部分属于存储可执行代码的文件;在运行时,这个文件部分被映射到系统链接器在程序初始化期间分配的内存区域,仅此而已(在 Linux 上,您可以在内存中看到这些部分的布局/proc/$PID/maps)。

至于类 Unix 系统上的 JIT 编译,我只能想到已通过启用标志的系统调用分配的内存区域mmapPROT_EXEC此调用由 POSIX 标准指定,并由 Linux 的系统链接器使用ld.so,以将任何本机可执行文件加载到内存中。此调用同样可用于在运行时分配新的可执行内存区域。

正如任何文件所暗示的那样,通常的堆通常受 OS/ MMU保护而不会被执行:/proc/$PID/maps

00dd4000-01292000 rw-p 00000000 00:00 0                  [heap]

这里rw-p意味着[heap]不能执行任何数据(尽管,例如,没有 PAE 的 32 位 x86 CPU 不是这种情况,它们没有硬件能力来阻止将某些内存数据作为代码运行),但可以读取/书面。

因此,VM 需要具有代码执行权限的专用内存区域。rwx确实,让我们在一些java进程内存布局中寻找内存区域:

# cat /proc/12929/maps | grep rwx        # I run a Java VM with PID 12929
f3700000-f3940000 rwxp 00000000 00:00 0  # - an unnamed executable & writable region

然后本地代码的执行是组装 JIT 编译的本地代码的问题,或者与位置无关(如编译共享对象代码,使用gccoption -fPIC)或使用mmap().

于 2013-09-24T12:58:10.880 回答