如何找出JVM应用于我的代码的优化?
JVM(尤其是HotSpot VM)因其在运行时可以应用的大量优化而闻名。
有没有办法查看某段代码,看看JVM实际上对它做了什么?
一个问题是“JVM实际上对它做了什么”在调用之间发生了变化,因为JVM可以自由地重新生成代码。
作为一个例子,我几天前调查了Hotspot与虚拟方法相比final
方法的作用。 从微观基准来看,我的结论是:
-
客户端JVM:如果该方法实际上是
final
(没有任何加载的类覆盖它),则JVM使用非虚拟调用。 之后,如果加载一个覆盖此方法的类,JVM将更改JIT代码以使调用成为虚拟。 因此宣布为final
并没有重大意义。 -
服务器JVM:这里的
final
似乎也没有相关性。 似乎发生的情况是,JVM为您第一次使用的任何类生成非虚拟调用,而与所加载的类无关。 之后,如果你从另一个类的对象进行调用,JVM将使用与此类似的东西修补所有调用(我猜它也会调用调用,以便它可以更改快速路径和慢速路径,如果它没有得到这是第一次):
if(object instanceof ClassOfNonVirtualCall){ 对ClassOfNonVirtualCall.method进行非虚拟调用 } else { 对object.method进行虚拟调用 }
如果您真的对查看生成的代码感兴趣,可以使用OpenJDK中的DEBUG JVM:
这是高度JVM特定的,您很可能需要在您正在查看的特定JVM中进行一些严肃的调查。
您可以在此处查看可用的HotSpot VM选项http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
以下是一个非常好的资源:
http://wikis.sun.com/display/HotSpotInternals/Home
特别有趣的是“LogCompilation工具”和“LogCompilation概述”链接(不能像我刚刚注册的那样发布直接链接)。
这是一个关于HotSpot优化的好页面。 通过查看编译器发出的字节码可以看到一些优化。 其他优化是动态的,仅在运行时存在。 例如,HotSpot可以进行堆栈替换 ,直接在运行时修改堆栈。