在这个程序的 main()
方法中创建了一个 Demo
对象的实例,并调用该实例的 square()
方法,然后显示 for
循环迭代变量的平方值 。编译并运行它:
$ javac Demo.java$ java Demo1 iterationSquare(i) = 1Time taken= 8432439--------------------------------2 iterationSquare(i) = 4Time taken= 54631--------------------------------...--------------------------------10 iterationSquare(i) = 100Time taken= 66498--------------------------------
上面的结果是由谁产生的呢?是解释器 , JIT 还是 AOT?在目前的情况下,它完全是通过解释产生的 。我是怎么得出这个结论的呢?只有代码被解释的次数必须超过某个阈值时,这些热点代码片段才会被加入 JIT 编译队列 。只有这时,JIT 编译才会发挥作用 。使用以下命令查看 JDK 11 中的该阈值:
$ java -XX:+PrintFlagsFinal -version | grep CompileThreshold intx CompileThreshold= 10000{pd product} {default}[...]openjdk version "11.0.13" 2021-10-19OpenJDK Runtime Environment 18.9 (build 11.0.13+8)OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8, mixed mode, sharing)
上面的输出表明,一段代码被解释 10,000 次才符合 JIT 编译的条件 。这个阈值是否可以手动调整呢?是否有 JVM 标志可以指示出方法是否被 JIT 编译了呢?答案是肯定的,而且有多种方式可以达到这个目的 。
使用 -XX:+PrintCompilation
选项可以查看一个方法是否被 JIT 编译 。除此之外,使用 -Xbatch
标志可以提高输出的可读性 。如果解释和 JIT 同时发生,-Xbatch
可以帮助区分两者的输出 。使用这些标志如下:
$ java -Xbatch-XX:+PrintCompilationDemo341b3java.util.concurrent.ConcurrentHashMap::tabAt (22 bytes)352n 0jdk.internal.misc.Unsafe::getObjectVolatile (native)353b3java.lang.Object::<init> (1 bytes)[...]210269n 0java.lang.reflect.Array::newArray (native)(static)211270b3java.lang.String::substring (58 bytes)[...]--------------------------------10 iterationSquare(i) = 100Time taken= 50150--------------------------------
注意 , 上面命令的实际输出太长了,这里我只是截取了一部分 。输出很长的原因是除了 Demo
程序的代码外,JDK 内部类的函数也被编译了 。由于我的重点是 Demo.java
代码,我希望排除内部包的函数来简化输出 。通过选项 -XX:CompileCommandFile
可以禁用内部类的 JIT:
$ java -Xbatch -XX:+PrintCompilation -XX:CompileCommandFile=hotspot_compiler Demo
在选项 -XX:CompileCommandFile
指定的文件 hotspot_compiler
中包含了要排除的包:
$ cat hotspot_compilerquietexclude java/* *exclude jdk/* *exclude sun/* *
第一行的 quiet
告诉 JVM 不要输出任何关于被排除类的内容 。用 -XX:CompileThreshold
将 JIT 阈值设置为 5 。这意味着在解释 5 次之后,就会进行 JIT 编译:
$ java -Xbatch -XX:+PrintCompilation -XX:CompileCommandFile=hotspot_compiler -XX:CompileThreshold=5 Demo471n 0java.lang.invoke.MethodHandle::linkToStatic(LLLLLL)L (native)(static)472n 0java.lang.invoke.MethodHandle::invokeBasic(LLLLL)L (native)473n 0java.lang.invoke.MethodHandle::linkToSpecial(LLLLLLL)L (native)(static)484n 0java.lang.invoke.MethodHandle::linkToStatic(L)I (native)(static)485n 0java.lang.invoke.MethodHandle::invokeBasic()I (native)486n 0java.lang.invoke.MethodHandle::linkToSpecial(LL)I (native)(static)[...]1 iteration6940n 0java.lang.invoke.MethodHandle::linkToStatic(ILIIL)I (native)(static)[...]Square(i) = 17848n 0java.lang.invoke.MethodHandle::linkToStatic(ILIJL)I (native)(static)7949n 0java.lang.invoke.MethodHandle::invokeBasic(ILIJ)I (native)[...]8654n 0java.lang.invoke.MethodHandle::invokeBasic(J)L (native)8755n 0java.lang.invoke.MethodHandle::linkToSpecial(LJL)L (native)(static)Time taken= 8962738--------------------------------2 iterationSquare(i) = 4Time taken= 26759--------------------------------10 iterationSquare(i) = 100Time taken= 26492--------------------------------
好像输出结果跟只用解释时并没有什么区别 。根据 Oracle 的文档 , 这是因为只有禁用 TieredCompilation
时 -XX:CompileThreshold
才会生效:
$ java -Xbatch -XX:+PrintCompilation -XX:CompileCommandFile=hotspot_compiler -XX:-TieredCompilation -XX:CompileThreshold=5 Demo1241njava.lang.invoke.MethodHandle::linkToStatic(LLLLLL)L (native)(static)1272njava.lang.invoke.MethodHandle::invokeBasic(LLLLL)L (native)[...]1 iteration18740njava.lang.invoke.MethodHandle::linkToStatic(ILIIL)I (native)(static)[...](native)(static)21254njava.lang.invoke.MethodHandle::invokeBasic(J)L (native)21255njava.lang.invoke.MethodHandle::linkToSpecial(LJL)L (native)(static)Time taken= 12337415[...]--------------------------------4 iterationSquare(i) = 16Time taken= 37183--------------------------------5 iteration21456bDemo::<init> (5 bytes)21557bDemo::square (16 bytes)Square(i) = 25Time taken= 983002--------------------------------6 iterationSquare(i) = 36Time taken= 81589[...]10 iterationSquare(i) = 100Time taken= 52393
推荐阅读
- 应采儿晒和大儿子逛吃vlog,Jasper自编自导自演,母子互动有趣
- 温和不刺激的护肤品有哪些 十大保湿温和护肤品品牌排行榜
- spss信度分析步骤,spss信度和效度分析怎么做
- 游本昌演济公时,遇3件怪事,至今无法用科学解释,拍完立刻出家
- 华为play4t和play4tpro有什么区别
- 虾和哪些蔬菜最佳搭配 大虾和哪些蔬菜一块炒
- 饭店名字大全和寓意吉字开头 饭店名字大全和寓意
- 孙姓发源地
- 豆浆和鸡蛋一起吃会消化不良?
- 客厅招财风水有哪些注意事项和禁忌 客厅招财风水有哪些注意事项