【发布时间】:2011-09-27 08:44:36
【问题描述】:
我有一个植根于接口并使用抽象基类实现的类层次结构。它看起来像这样:
interface Shape {
boolean checkFlag();
}
abstract class AbstractShape implements Shape {
private boolean flag = false;
protected AbstractShape() { /* compute flag value */ }
public final boolean checkFlag() { return flag; }
}
interface HasSides extends Shape {
int numberOfSides();
}
interface HasFiniteArea extends Shape {
double area();
}
class Square extends AbstractShape implements HasSides, HasFiniteArea {
}
class Circle extends AbstractShape implements HasFiniteArea {
}
/** etc **/
当我使用 VisualVM 对正在运行的代码进行采样时,AbstractShape.checkFlag() 似乎从未内联并消耗 14% 的总程序运行时间,这对于一个如此简单的方法来说是令人讨厌的,甚至对于如此频繁调用的方法。
我已在基类上标记了最终方法,并且(当前)所有实现“Shape”接口的类都扩展了 AbstractShape。
我是否正确解释了 VisualVM 示例结果?有什么方法可以说服 JVM 内联此方法,还是我需要删除接口并只使用抽象基类? (我不希望这样做,因为层次结构包括 HasFiniteArea 和 HasSides 等接口,这意味着层次结构没有完美的树形)
编辑:明确地说,这是一种在 any 宇宙中应该 内联的方法。在 2 分钟的执行过程中,它被调用了超过 4.2 亿次 次,并且由于它没有内联并且仍然是虚拟调用,因此它占运行时的 14%。我要问的问题是是什么阻止了 JVM 内联此方法,我该如何解决?
【问题讨论】:
-
什么的 14%? 1毫秒?这是您可能用 Java 编写的最快的方法。它只返回字段的值。为什么要内联?
-
这可能是分析时未完成内联的问题...
-
@ThorbjørnRavnAndersen 我认为这对于分析是正确的,但我使用 VisualVM 进行采样。这也会干扰内联吗?
-
你的程序在剩下的 86% 的时间里做什么?
标签: java optimization jvm compiler-optimization