Java invokevirtual在JVM中的实现

Java invokevirtual在JVM中的实现,java,methods,jvm,Java,Methods,Jvm,我原以为Java虚拟机将使用一个简单的查找表进行正常的方法调用:该对象包含一个指向查找表的指针,其中包含类实现的所有方法(包括由超类实现的方法)的地址。一个特定的方法简单地由该表中的索引表示。JVM在表中查找方法的地址,并跳转到该地址 但是JVM规范指定了一个长而复杂的过程,用于在运行时查找正确的方法(请参阅): 无符号indexbyte1和indexbyte2用于构造索引 进入当前类[该类]的运行时常量池,该类必须是 方法的符号引用,该方法提供名称和描述符 方法以及对其中的类的符号引用 方法有

我原以为Java虚拟机将使用一个简单的查找表进行正常的方法调用:该对象包含一个指向查找表的指针,其中包含类实现的所有方法(包括由超类实现的方法)的地址。一个特定的方法简单地由该表中的索引表示。JVM在表中查找方法的地址,并跳转到该地址

但是JVM规范指定了一个长而复杂的过程,用于在运行时查找正确的方法(请参阅):

无符号indexbyte1和indexbyte2用于构造索引 进入当前类[该类]的运行时常量池,该类必须是 方法的符号引用,该方法提供名称和描述符 方法以及对其中的类的符号引用 方法有待找到。已解析命名的方法。[……]那么 invokevirtual指令如下所示

如果C包含重写的实例方法m的声明 (§5.4.5)解析方法,则m是要调用的方法,以及 查找过程终止

否则,如果C有一个超类,则使用相同的查找过程 使用C的直接超类递归执行;方法 被调用是此查找的递归调用的结果 程序

我认为这一复杂而漫长的过程需要很长时间。因为它是为每个普通的方法调用完成的,所以基于JVM的程序几乎所有的时间都将花费在这个过程中


这真的是在真实(Oracle)JVM中实现的吗?或者JVM对查找表进行JIT类型的编译?是否有具体JVM如何实际实现这一点的描述?

Java语言规范或Java虚拟机规范中没有规定任何特定的实现策略。每个实现者都可以自由选择他们想要的任何实现策略,只要结果与他们实现规范中描述的算法相同

换句话说,规范中的算法描述的是最终结果,而不是配方

最简单和最明显的可能优化就是愚蠢地执行所描述的算法,但缓存结果,而不是将其丢弃

大多数现代高性能JVM都源自Smalltalk VM,并使用Smalltalk社区在20世纪80年代发明的技术

EclipseOpenJ9以IBMJ9开始其生命,而IBMJ9又源于IBMVisualAgeforJava通用虚拟机(能够无缝地执行JVM字节码和Smalltalk字节码的混合),而IBM VisualAgeforSmalltalk虚拟机又基于IBMVisualAgeforSmalltalk虚拟机

Oracle HotSpot基于LongView的Animorphic Smalltalk虚拟机,后者又基于Self虚拟机。(Animorphic Smalltalk虚拟机也是谷歌V8 ECMAScript引擎的原始基础。)

Azul-Zing源于HotSpot。Oracle实验室Maxine RVM是由一些老的Smalltalk和Self开发人员基于Klein VM(一个用Self编写的实验性元循环Self VM)的思想开发的

消除动态运行时虚拟消息调度开销的一些最著名的技术有

  • 设备化–将动态运行时虚拟消息调度转变为静态方法查找:
  • Callsite Customization–编译多个不同版本的代码,每个版本针对特定的接收器类型:
  • 动态类型反馈:
  • 动态类型推断:
  • –记住上次查找的结果
    • ,
    • 双纯内联缓存
    • :
    • ,
  • 投机内联:
  • 各种其他形式的自适应优化:
[您会注意到,几乎所有的源代码都是针对Self或Smalltalk的。两个主要原因是Self开创了许多此类技术,Smalltalk和Smalltalk VM对Java和JVM产生了重大影响。]

我最熟悉的JVM(Eclipse OpenJ9、Oracle HotSpot、Oracle实验室Maxine RVM、Azul Zing)实现了上述大部分功能


Java 7中JVM规范中引入的
invokedynamic
字节码允许程序员访问上述优化,但提供自己的方法查找算法,而不是硬编码到JVM中的算法。这使得在JVM之上为方法查找算法与Java不兼容的语言创建高性能实现成为可能。

Java语言规范或Java虚拟机规范中没有规定任何特定的实现策略。每个实现者都可以自由选择他们想要的任何实现策略,只要结果与他们实现规范中描述的算法相同

换句话说,规范中的算法描述的是最终结果,而不是配方

最简单和最明显的可能优化就是愚蠢地执行所描述的算法,但缓存结果,而不是将其丢弃

大多数现代高性能JVM都源自Smalltalk VM,并使用Smalltalk社区在20世纪80年代发明的技术

EclipseOpenJ9以IBMJ9开始其生命,而IBMJ9又源于IBMVisualAgeforJava通用虚拟机(能够无缝地执行JVM字节码和Smalltalk字节码的混合),而IBM VisualAgeforSmalltalk虚拟机又基于IBMVisualAgeforSmalltalk虚拟机

Oracle HotSpot基于LongView的Animorphic Smalltalk VM,它在