JVM(尤其是 HotSpot VM)以其可以在运行时应用的大量优化而闻名。
有没有办法查看某段代码并查看 JVM 实际对它做了什么?
JVM(尤其是 HotSpot VM)以其可以在运行时应用的大量优化而闻名。
有没有办法查看某段代码并查看 JVM 实际对它做了什么?
一个问题是,由于 JVM 可以自由地重新生成代码,因此“JVM 实际对它所做的事情”在调用之间会发生变化。
作为一个例子,我几天前调查了 Hotspot 与final
虚拟方法相比对方法的作用。从微基准来看,我的结论是:
客户端 JVM:如果方法有效 final
(没有任何加载的类覆盖它),则 JVM 使用非虚拟调用。之后,如果您加载一个覆盖此方法的类,JVM 将更改 JIT 代码以使调用虚拟化。所以声明 asfinal
没有显着相关性。
服务器JVM:这里final
似乎也没有相关性。似乎发生的是,JVM 会为您第一次使用的任何类生成一个非虚拟调用,而与加载的任何类无关。之后,如果您从另一个类的对象进行调用,JVM 将使用与此类似的东西修补所有调用(我猜它也会分析调用,因此如果没有得到,它可以更改快速路径和慢速路径第一次就对了):
if (object instanceof ClassOfNonVirtualCall) { 对 ClassOfNonVirtualCall.method 进行非虚拟调用 } 别的 { 对 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 可以进行堆栈替换,在运行时直接修改堆栈。