gpt4 book ai didi

java - 如果一个方法由其显式类型调用,它对运行时性能有影响吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:57:05 26 4
gpt4 key购买 nike

我目前正在编写一个创建 Java 字节码并编写方法调用的应用程序。到目前为止,编写此字节代码的模块没有关于调用方法调用的实例的实际类型的信息,但它确实知道为其定义特定方法的类型。例如:

class Foo {   
public void foo() { }
}

class Bar extends Foo {
public void bar() { }
}

引擎的当前版本将执行

INVOKEVIRTUAL Foo.foo

甚至在 Bar 类型的对象上,因为它知道 foo 是在 Foo 中定义的。这在 JVM 中是合法的(当然),但 Java 编译器会将其翻译成

INVOKEVIRTUAL Bar.foo

当它是“正常的”Java 源代码时。我目前想知道 JVM 是否实际使用了显式子类型的信息,或者在加载类时是否忽略/优化了它。我想知道,因为 validator 无论如何都会弄清楚实际类型,并且不会让我编写非法方法调用,我想知道为什么运行时不会在已经可用时使用此信息。我特别想知道当父类(super class)型是接口(interface) (INVOKEINTERFACE) 时它是否会对性能产生影响,如果 JVM 无法确定实际类型,则无法使用虚拟方法表。

我当然可以扩展我的模块,但我需要向它提供额外的信息,这会使我的代码膨胀,如果它没有效果,我不想这样做。所以我问:类型会影响性能还是 JVM 会处理这个显式解析?

最佳答案

字节码中的任何区别都不会影响 JIT 编译代码的性能。

HotSpot 会定期为每个 invokevirtual 调用站点保留一个类型配置文件。如果记录表明只有一种类型被分派(dispatch),JIT 编译器会将其视为 invokespecial 调用,基本上是直接跳转到被调用者,甚至是被调用者的内联。

上面描述了最难情况的优化,一个完全通用的虚方法。 HotSpot 还知道哪些方法是有效的最终:在加载类的集合中,没有出现对该方法的覆盖。在那种情况下,HotSpot 的处理与上述类似,但省略了一些指令(执行类型断言的指令)。

我还付出了一些努力来破解 .class 文件,以便 invokevirtual 指令被 invokespecial 取代。结果是 VerifyError:

Exception in thread "main" java.lang.VerifyError: 
Bad invokespecial instruction: current class isn't assignable to reference class.

您只能对当前类或其祖先类的方法使用invokespecial,这实际上是specified by the Java Virtual Machine Specification, §4.9.2 :

Each invokespecial instruction must name an instance initialization method (§2.9), a method in the current class, or a method in a superclass of the current class.

关于java - 如果一个方法由其显式类型调用,它对运行时性能有影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21679998/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com