Java 超级方法的 vtable
Java vtable for super methods
当我们有两个时 类:
class Foo {
void foo() {
System.out.println("foo");
}
}
和:
class Bar extends Foo{
void bar() {
System.out.println("bar");
}
}
Bar clazz 对象是否在 vtable 中存储对 foo() 和 bar() 方法的引用,或者在 Bar 的 vtable 中仅引用 bar() 方法并访问 foo() 方法 jvm 访问 Bar clazz 对象,然后是 Foo clazz 对象,然后在其 vtable 中找到 foo() 方法?
是不是更像这样:
或者那个:
或者这可能没有在规范中描述并且可能取决于 JVM 实现?
JVM 规范没有规定如何实现虚方法调用。它甚至没有引用 vtable 的概念。 JVM 实现可以选择这种或另一种方式,只要它的行为符合预期即可。
至于 HotSpot JVM,Java SE 虚拟机的参考实现,它的工作方式与您的第一张图片相同,即 class 的单个 vtable 包含其所有虚拟方法,包括继承的。
------------------ ------------------
| Foo.class vtable | | Bar.class vtable |
|------------------| |------------------|
| clone | | clone | \
| equals | | equals | | java.lang.Object
| hashCode | | hashCode | / virtual methods
| ... | | ... |
| foo | | foo | } Foo virtual methods
------------------ | bar | } Bar virtual methods
------------------
这样的布局保证 Foo
class 的所有后代都将在 vtable 中的相同索引处引用 foo
方法。这允许足够快地进行虚拟调用,即在恒定时间内,即使对于 megamorphic 方法也是如此。
当我们有两个时 类:
class Foo {
void foo() {
System.out.println("foo");
}
}
和:
class Bar extends Foo{
void bar() {
System.out.println("bar");
}
}
Bar clazz 对象是否在 vtable 中存储对 foo() 和 bar() 方法的引用,或者在 Bar 的 vtable 中仅引用 bar() 方法并访问 foo() 方法 jvm 访问 Bar clazz 对象,然后是 Foo clazz 对象,然后在其 vtable 中找到 foo() 方法?
是不是更像这样:
JVM 规范没有规定如何实现虚方法调用。它甚至没有引用 vtable 的概念。 JVM 实现可以选择这种或另一种方式,只要它的行为符合预期即可。
至于 HotSpot JVM,Java SE 虚拟机的参考实现,它的工作方式与您的第一张图片相同,即 class 的单个 vtable 包含其所有虚拟方法,包括继承的。
------------------ ------------------
| Foo.class vtable | | Bar.class vtable |
|------------------| |------------------|
| clone | | clone | \
| equals | | equals | | java.lang.Object
| hashCode | | hashCode | / virtual methods
| ... | | ... |
| foo | | foo | } Foo virtual methods
------------------ | bar | } Bar virtual methods
------------------
这样的布局保证 Foo
class 的所有后代都将在 vtable 中的相同索引处引用 foo
方法。这允许足够快地进行虚拟调用,即在恒定时间内,即使对于 megamorphic 方法也是如此。