开发者

How do I convince the JVM to inline an interface method?

I have an class hierarchy rooted in an interface and implemented with an abstract base class. It something looks like this:

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 **/

When I sample the running code with VisualVM, it appears that AbstractShape.checkFlag() is never inlined and consumes 14% of total program running time, which is obscene for a method this simple, even for a method called so frequently.

I have marked the method final on the base class, and (currently) all classes implementing the "Shape" interface extend AbstractShape.

Am i interpreting the VisualVM sample results correctly? Is there any way to convince the JVM to inline this method or would I need to tear out the interfaces and just use an abstract base class? (I would prefer not to because the hierarchy includes interfaces like HasFiniteArea and HasSides which mean the hierachy does not have a perfect tree form)

EDIT: to be 开发者_如何学Pythonclear, this is a method that in any universe should be inlined. It is called more than 420 million times during a 2 minute execution and, because it is not inlined and remains a virtual call, it accounts for 14% of runtime. The question I'm asking is what is preventing the JVM from inlining this method and how do i fix it?


Here is quote from the Wikipedia

A common misconception is that declaring a class or method final improves efficiency by allowing the compiler to directly insert the method inline wherever it is called. This is not completely true; the compiler is unable to do this because the classes are loaded at runtime and might not be the same version as the ones that were just compiled. Further, the runtime environment and JIT compiler have the information about exactly which classes have been loaded, and are able to make better decisions about when to inline, whether or not the method is final.

See also this article.


The default compiler threshold is 10000. -XX:CompilerThreshold= This means a method or a loop (for the server JVM) has to be called at least 10000 times before it is compiled to native code.

After it has been compiled it can be inlined, however the call stack does show this. It is smart enough to know the inlined code came from another method and you never see a truncated call stack.

profilers try sample code and assign time. It doesn't always do a great job and you get methods which are obvious not time consumers being assigned CPU time. VisualVM is a free profiler and it is implementing in Java. If you use a profiler like YourKit you can get more accurate results as it uses native code e.g. doesn't create garbage.


After extensive experimentation, I could not get the Sun JDK 6 to inline this method when called on the interface.

Fortunately, there were a limited number of call sites involved, and changing

public void paint(Shape shape) {
  if(shape.checkFlag()) { /* do stuff */ }
} 

to

public void paint(Shape shape) {
  if(((AbstractShape)shape).checkFlag()) { /* .. */ }
}

is enough of a hint to get the JVM to inline the method. Running time of the calculation in question dropped 13% compared to the original runtime of 6 minutes.


From the literature I've read on old versions of JVM's by declaring methods final it would determine it to transform that method inline. Now you don't have to specify that method to be final to optimize the code.

You should let the JVM optimize the code, and make the method final only if you explicitly don't want that method overridden. The JVM probably doesn't make your method inline because its own optimization is faster, considering the rest of the application's code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜