Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当java jvm编译字节码时,该代码在进程空间中的位置如何?_Java_Memory_Process_Jvm_Jvm Hotspot - Fatal编程技术网

当java jvm编译字节码时,该代码在进程空间中的位置如何?

当java jvm编译字节码时,该代码在进程空间中的位置如何?,java,memory,process,jvm,jvm-hotspot,Java,Memory,Process,Jvm,Jvm Hotspot,当jvm(在我的例子中是热点)将某些代码路径永久编译成机器代码时,机器代码存储在哪里?在进程内存的.text段中?在进程的堆中 我不是在说JITing。据我所知,JIT将编译并运行字节码,而不会将编译后的代码保存在任何地方。但是,当jvm保存代码时——它在进程空间的什么地方保存代码呢? ... 正如评论和回答所指出的,事实上,我所要求的一切都是JIT的一部分 编辑: 根据我下面的评论,我特别提到的情况在这里被记录为“自适应优化”:首先,您描述的是JIT——特别是它在Hotspot中的工作方式

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

我不是在说JITing。据我所知,JIT将编译并运行字节码,而不会将编译后的代码保存在任何地方。但是,当jvm保存代码时——它在进程空间的什么地方保存代码呢? ... 正如评论和回答所指出的,事实上,我所要求的一切都是JIT的一部分

编辑:


根据我下面的评论,我特别提到的情况在这里被记录为“自适应优化”:

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


要回答您关于代码在运行时保存在何处的问题,请将代码保存在进程堆中,并更新对象Klass文件中指向方法代码的指针以指向它。还有一种叫做OSR(在堆栈上替换)的东西,用于直接在堆栈上编译长时间运行的循环。

我没有使用过生产质量的VM,但这是我的五美分

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

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

正如任何
/proc/$PID/maps
文件所建议的那样,通常的堆通常由OS/保护,不被执行:

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

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

# 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编译的本机代码的问题,可以是独立地(像编译共享对象代码一样,使用
gcc
选项
-fPIC
),也可以使用
mmap()
返回的地址

除了在JIT期间,JVM什么时候生成编译后的代码?JVM不会将字节码永久编译为本机代码。因此,它不会持久地存储在任何地方。@AlexanderBird:这就是JITting。感谢您回答我的问题并解释我想问的问题:)编译后的代码是否存储在所讨论的同一个“代码缓存”中?如果是这样,如果我增加-Xmx,这会影响代码缓存吗?是的,我认为最好使用本文中提到的显式选项,即
-XX:ReservedCodeCacheSize
,这不太正确:进程堆通常受到操作系统的保护,不会被执行。