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