所以我有这个方法,用Java编写:
public void myMethod(int y){
int x = 5 + y;
doSomething(x);
}
并假设我的应用程序多次调用此函数..
当在Java虚拟机上运行该方法的编译代码时,JVM将首先解释该方法。然后一段时间后,如果我理解正确的话,它会决定将其编译为机器语言。
在此刻,
会被内存中的机器码覆盖吗?如果覆盖的话,大小差异的问题怎么解决?如果将其写入内存中的其他位置,加载到内存中的字节码是否会被释放?而且,如果字节码和 jit 编译的代码都在内存中,当应用程序再次调用该方法时,JVM 如何决定执行 jit 编译的代码而不是字节码?
HotSpot JVM 有一个Method http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/9989538b7507/src/share/vm/oops/method.hpp#l40Metaspace 中的结构(或早期版本中的 PermGen)。
它包含永远不会被覆盖的方法字节码指向已编译代码的指针 http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/9989538b7507/src/share/vm/oops/method.hpp#l135,最初为 NULL,直到该方法被编译。
一个方法可以有多个入口点:
-
_i2i_entry
- 指向字节码解释器的指针。
-
_code->entry_point()
- JIT 编译代码的入口点。编译后的方法驻留在CodeCache
- 用于VM动态生成代码的本机内存的特殊区域。
-
i2c
and c2i
适配器从解释器调用编译后的代码,反之亦然。需要这些适配器,因为解释方法和编译方法具有不同的调用约定(如何传递参数的方式,如何构造框架等)
编译的方法可能有不常见的陷阱,在极少数情况下会回退到解释器。此外,Java方法可以动态重新编译多次,因此JVM不能丢弃原始字节码。无论如何释放它是没有意义的,因为字节码通常比编译后的代码小得多。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)