如何查找JVM对我的代码进行了哪些优化?

10

JVM(尤其是HotSpot VM)以运行时应用大量优化而闻名。

有没有办法查看某个代码片段,看看JVM实际上对其做了什么?

4个回答

6
一个问题是“JVM实际上对其所做的事情”在调用之间发生变化,因为JVM可以自由重新生成代码。
例如,我几天前调查了Hotspot对final方法与虚拟方法的处理方式。根据微基准测试,我的结论是:
- 客户端JVM:如果该方法实际上是final的(没有任何加载的类覆盖它),JVM将使用非虚拟调用。然后,如果您加载覆盖此方法的类,JVM将更改JIT编译的代码以使调用变为虚拟。因此,声明为final没有显着的相关性。 - 服务器JVM:这里final似乎也没有相关性。似乎发生的是JVM会为您第一次使用的任何类生成非虚拟调用,而与加载的任何类无关。之后,如果您从另一个类的对象进行调用,JVM将使用类似于以下内容的东西修补所有调用(我猜它还会分析调用,以便在第一次时快速路径和慢速路径都正确):
如果 (object instanceof ClassOfNonVirtualCall) { 执行非虚拟调用到 ClassOfNonVirtualCall.method } else { 执行虚拟调用到 object.method }

如果您真的对生成的代码感兴趣,可以尝试使用来自OpenJDK的DEBUG JVM:

http://dlc.sun.com.edgesuite.net/jdk7/binaries/index.html

http://wikis.sun.com/display/HotSpotInternals/PrintAssembly


服务器VM确实会为两个类内联特殊情况下的代码——双态内联。我相信这个功能是为了支持NIO直接缓冲区和Java堆缓冲区而实现的。 - Tom Hawtin - tackline

4

热点是我最感兴趣的JVM实现。 - soc

3

嗨,ijuma!很高兴在这里见到你! - soc

2

这是一个关于 HotSpot 优化 的好文章。

编译器所产生的字节码可以展现出其中一些优化。其他优化则是动态的,只存在于运行时。例如,HotSpot 可以通过 栈上替换 来直接在运行时修改堆栈。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接