Java 如何找出JVM对我的代码应用了哪些优化?

Java 如何找出JVM对我的代码应用了哪些优化?,java,optimization,compiler-construction,jvm,vm-implementation,Java,Optimization,Compiler Construction,Jvm,Vm Implementation,JVM(特别是HotSpot VM)以其在运行时可以应用大量优化而闻名 有没有一种方法可以查看某段代码并查看JVM对其实际做了什么?这是非常特定于JVM的,您很可能需要对正在查看的特定JVM进行一些认真的调查 您可以在这里看到可用的HotSpot VM选项,一个问题是“JVM实际对它做了什么”在调用之间会发生变化,因为JVM可以自由地重新生成代码 作为一个例子,几天前我调查了Hotspot与虚拟方法相比对final方法的作用。根据微基准点判断,我的结论是: 客户机JVM:如果方法实际上是fin

JVM(特别是HotSpot VM)以其在运行时可以应用大量优化而闻名


有没有一种方法可以查看某段代码并查看JVM对其实际做了什么?

这是非常特定于JVM的,您很可能需要对正在查看的特定JVM进行一些认真的调查

您可以在这里看到可用的HotSpot VM选项,一个问题是“JVM实际对它做了什么”在调用之间会发生变化,因为JVM可以自由地重新生成代码

作为一个例子,几天前我调查了Hotspot与虚拟方法相比对
final
方法的作用。根据微基准点判断,我的结论是:

  • 客户机JVM:如果方法实际上是
    final
    (没有任何加载的类覆盖它),JVM将使用非虚拟调用。之后,如果加载一个重写此方法的类,JVM将更改JIT代码,使调用成为虚拟的。因此,声明为
    final
    没有显著相关性

  • 服务器JVM:这里的
    final
    似乎也没有任何关联。看起来,JVM会为您第一次使用的任何类生成一个非虚拟调用,与加载的任何类无关。之后,如果您从另一个类的对象进行调用,JVM将使用类似的东西修补所有调用(我猜它也会分析调用,以便在第一次没有正确处理时可以更改快速路径和慢速路径):

if(非虚拟调用类的对象实例){ 对ClassOfNonVirtualCall.method执行非虚拟调用 }否则{ 对object.method执行虚拟调用 } 如果您真的对生成的代码感兴趣,可以使用OpenJDK中的调试JVM:


以下是一个非常好的资源:

特别有趣的是“日志编译工具”和“日志编译概述”链接(由于我刚刚注册,无法发布直接链接)。

这是一个很好的页面。
通过查看编译器发出的字节码可以看到一些优化。其他优化是动态的,只在运行时存在。例如,HotSpot可以在运行时直接修改堆栈

热点将是我最感兴趣的JVM实现!很高兴在这里见到你!实际上,服务器虚拟机将为两个类(双晶片内联)内联特例代码。我相信这个特性是为了支持NIO direct和Java堆缓冲区而实现的。 if (object instanceof ClassOfNonVirtualCall) { do non-virtual call to ClassOfNonVirtualCall.method } else { do virtual call to object.method }