源码和机器指令码
源码就是程序员写的代码,这里不需多说,先上一段hello word代码,这就是源码
统统都要转化成机器能识别的机器指令码,交给CUP执行
我们都知道,JVM虚拟机对于程序员和计算机硬件来说,它是一个翻译。就是把程序员能看懂的源码进行翻译,然后变成机器能看懂的机器码,最后执行
先看看翻译后的机器码大概是这样:其实就是一条条的指令
编译
那么对于java来说,JVM是如何将我们写的代码变成指令,让CPU执行呢??它做了三件事:
1、将源码通过编译工具,就是我们都知道的javac,将代码进行分析、处理等一系列的操作后,生成 .class文件
2、编译完成后,就需要翻译了,这里有两种可能:
(1)对于一般的代码,JVM使用java解释器,也就是java,将.class文件逐行进行翻译成机器码
(2)对于热点代码(就是多次执行的同一段代码,比如一个方法循环执行1万次),JVM会选择JIT解释器(just-in-time compler 即时编译器)。JIT解释器是将整个热点代码块进行翻译成机器码,并存储起来,下次执行就直接将存储的机器码交给CPU就可以
3、将翻译后的机器码交给CPU执行,完成我们需要的运算逻辑
对于上面的流程可以发现,JIT解释器和java解释器,都是JVM的解释器,至于他们什么时候被分配使用,默认由JVM来决定。但他们的作用和运行逻辑是有区别的
对于java解释器来说,可以理解为,来一行代码我就解释一行,不管有没有执行过
对于JIT解释器来说,可以理解为,JVM会先进行计算,选出一些热点代码,然后交给我,我就先将这些代码进翻译后,再存起来,下次再执行,就不用再翻译一遍,提高了效率
这两个解释器哪个更快呢?
在翻译的时候,当然是java解释器更快了,因为它每次只解释一行
对于执行,当然是JIT更快了,因为它翻译一次,以后都不用再翻译了
JIT这么牛X,为什么还要用java解释器呢?其实很简单,首先不是每一句代码都是热点代码,其次JIT翻译比java解释器更慢,最后,存储也是要内存的嘛
AOT Ahead-Of-Time - 预先编译
就是直接将java源码编译成机器码,咋一看感觉老牛X了,这都不用经过class编译了,看起来很厉害的样子
其实不然,首先,AOT的核心思想是Ahead预先编译,也就是说在程序运行前就已经编译好了。对于程序来说,执行的代码、参数等都是动态的,随时根据业务变化的。你一开始就给我编译完了,我的动态资源、代码怎么办?而且,编译的速度很慢。所以我的理解是,这玩意适合一些固定的初始化代码,或者是解决JIT的编译消耗