jvm执行方法有两种方式:解释执行和编译执行。
编译执行是直接执行本地的机器码,编译执行的效率要高于解释执行的效率。
那么,为什么不直接把java代码编译成机器码呢,这样运行起来会更快?
直接编译成机器码的话,那不就是C语言的做法了么。java有一个特性,是可以运行中动态加载类。
要支持运行中动态加载类这个特性,就没法做到全部编译成机器码,编译的时候都不知道运行时的类是什么,没法编译。
还有一个原因是,java编译的代码,是要到不同的平台上运行的,搞成机器码就平台相关的了。
上面是为什么在编译期间不把代码编译成机器码的原因。
那么还有还有JIT呢,JIT是运行期间将热点代码编译为机器码。为什么要只编译热点代码,把所有运行时代码都编译了不好么。
1. 关联的类那么多,编译也是要时间的,启动一个应用,还要让用户等着代码编译完,用户没那个耐心;
2. 对于那些执行频率低的代码段,编译执行省下的时间比解释执行时间少不了多少;
3. 一些编译优化的措施,需要收集运行时的数据再做决定,启动的时候就编译,那些运行时数据还没有。
什么优化措施,要收集运行时数据?
比如编译优化的时候要不要将方法内联。方法内联可以减少一次函数调用的开销,但是会使得总的代码量增大。如果把所有方法都内联,在方法缓存紧张的情况下,会出现缓存命中率变低,因为方法代码量大了,缓存能够存储的方法数目就少了。所以,要根据方法的调用次数来决定内联值不值得。