需要特别注意的是,修改被 AOT 编译了的源代码后,一定要重新生成 .so
库文件 。否则,过时的的 AOT 编译库文件不会起作用 。例如,修改 square()
方法,使其计算立方值:
//Demo.javapublic class Demo {public int square(int i) throws Exception {return(i*i*i);}public static void main(String[] args) throws Exception {for (int i = 1; i <= 10; i++) {System.out.println("" + Integer.valueOf(i)+" iteration");long start = System.nanoTime();int r= new Demo().square(i);System.out.println("Square(i) = " + r);long end = System.nanoTime();System.out.println("Time taken= " + (end-start));System.out.println("--------------------------------");}}}
重新编译 Demo.java
:
$ java Demo.java
但不重新生成 libDemo.so
。使用下面命令运行 Demo
:
$ java -XX:+UnlockExperimentalVMOptions -Xbatch -XX:+PrintCompilation -XX:CompileCommandFile=hotspot_compiler -XX:-TieredCompilation -XX:CompileThreshold=3 -XX:AOTLibrary=./libDemo.so -XX:+PrintAOT Demo201loaded./libDemo.soaot library741njava.lang.invoke.MethodHandle::linkToStatic(LLLLLL)L (native)(static)2 iterationsqrt(i) = 8Time taken= 43838--------------------------------3 iteration13756bDemo::<init> (5 bytes)13857bDemo::square (6 bytes)sqrt(i) = 27Time taken= 534649--------------------------------4 iterationsqrt(i) = 64Time taken= 51916[...]10 iterationsqrt(i) = 1000Time taken= 47132
可以看到,虽然旧版本的 libDemo.so
被加载了 , 但 JVM 检测出它已经过时了 。每次生成 .class
文件时,都会在类文件中添加一个指纹,并在 AOT 库中保存该指纹 。修改源代码后类指纹与旧的 AOT 库中的指纹不匹配了,所以没有执行 AOT 编译生成的原生机器码 。从输出可以看出,现在实际上是 JIT 在起作用(注意 -XX:CompileThreshold
被设置为了 3) 。
AOT 和 JIT 之间的权衡如果你的目标是减少 JVM 的预热时间,请使用 AOT,这可以减少运行时负担 。问题是 AOT 没有足够的数据来决定哪段代码需要预编译为原生代码 。相比之下,JIT 在运行时起作用 , 却对预热时间有一定的影响 。然而,它将有足够的分析数据来更高效地编译和反编译代码 。
推荐阅读
- 应采儿晒和大儿子逛吃vlog,Jasper自编自导自演,母子互动有趣
- 温和不刺激的护肤品有哪些 十大保湿温和护肤品品牌排行榜
- spss信度分析步骤,spss信度和效度分析怎么做
- 游本昌演济公时,遇3件怪事,至今无法用科学解释,拍完立刻出家
- 华为play4t和play4tpro有什么区别
- 虾和哪些蔬菜最佳搭配 大虾和哪些蔬菜一块炒
- 饭店名字大全和寓意吉字开头 饭店名字大全和寓意
- 孙姓发源地
- 豆浆和鸡蛋一起吃会消化不良?
- 客厅招财风水有哪些注意事项和禁忌 客厅招财风水有哪些注意事项