【问题标题】:how does the jvm handle polymorphism and its optimizationjvm如何处理多态性及其优化
【发布时间】:2012-05-19 19:55:18
【问题描述】:

我的情况是有一个带有方法 m 的接口 I,以及行为不同的两个实现类 A 和 B。

A 和 B 的对象仅将内存用于它们的值和引用类型,而不是用于它们的方法。存储在类型 I 变量中的 A 对象与引用(指针大小开销)加上对象大小一起存储。现在调用方法 m。现在这一位信息存储在哪里,必须从 B 类调用 A 类的方法 m?

这个问题也让我对 C++ 虚拟方法感到厌烦。

interface I { void m(); }
class A implements I { void m(){println("a");} }
class B implements I { void m(){println("b");} }

【问题讨论】:

  • 谁说“A 和 B 的对象仅将内存用于其值和引用类型,而不用于其方法”?这是一个相当大胆的断言(而且可能是错误的)。
  • 可能是真的,这个假设可能是错误的,这正是我问这个问题的原因。但是我的 visualVM 分析告诉我,只使用了值类型和引用的空间,而不是方法。但我不确定我能多认真地接受这些测试,因为我不知道还有哪些优化。

标签: c++ jvm polymorphism virtual


【解决方案1】:

在 C++ 中,每个对象通常包含一个指向函数地址表(vtable)的隐藏指针(vptr)。每个类有一个 vtable,包含其虚函数实现的地址。见http://en.wikipedia.org/wiki/Virtual_method_table

我认为 Java 以类似的方式实现事物(虽然我没有研究过)。

【讨论】:

  • 这意味着具有虚函数的类的对象总是比没有虚函数的对象大一个指针大小?是否存在这种开销可能会减少到一个字节的情况?
  • @Arne:我想这在理论上是可能的。但我怀疑任何实现都会这样做(首先它将层次结构中的类总数限制为 256)。
【解决方案2】:

在实际执行代码 (JIT) 中,至少 Hotspot JVM 有时可以直接调用正确的方法(有效地对其进行去虚拟化)如果它可以确定它是哪一个。由于它还处理类加载,因此类层次结构是已知的,因此如果它周围没有 B 的实例,则可以确定它是例如 A(单态)。如果稍后创建 B 的实例,它可以反优化并仍然进行一些优化(仍然只有两个替代方案,双态)。

【讨论】:

  • 我确信 Hotspot 可以做很多优化,但假设 jvm 不知道对象来自 A 类还是 B 类。
猜你喜欢
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
  • 2018-07-20
相关资源
最近更新 更多