00:00
好,那么大家呢,对执行引擎的这个作用和执行过程啊,有一个直观的了解之后啊,下边呢,咱们来看一看这个Java代码,它在编译和执行过程当中的一些细节问题啊,编译和执行这是我们这一节中主要谈的两个重要的这个词啊好,首先的话呢,我们来看这个图,这个图里边啊,诶猛一下看呢,感觉还挺复杂的是吧?哎,而且我这还用了三种不同的颜色啊,这是什么意思啊,咱们来理解一下,哎,我给大家呢做一个剖析,那首先说这个位置啊,是咱们的一个起始位置,叫程序源码,也就是说呢,咱们这个执行程序的话呢,这就是一开始你写的这个程序,不管呢,你是点Java结尾的这个Java程序,还是点这个CP结尾的这个,呃,C加加程序还是这个Python程序等等,这呢就是你的起始的这个原文件啊,那么最终的目的呢,咱们都是希望呢,把这原文件呢,做一个执行。那这里边儿这个绿色的呢,是一条路径,这里边这个蓝色的呀,也是一条路径啊,就是另外的一条路径,哎,所谓的目标代啊,就是目标代码啊,就是我们所谓的这个啊,最后的这个机器指令了啊,本地代码这样,那这呢是有一个分叉,那这个呢,我还用了三种不同的颜色来区分啊,我们把这个图呢,可以做一个剖析啊,首先呢,我们来看这个说大部分的这个程序代码。
01:16
来成序代码转化成物理机的目标代码,或者这是虚拟异能,呃,执行的这个指令集之前都需要经过上图中的各个步骤啊,就是说白了就是这呢是我们的起始点,这呢是这个终点,那你你都需要经历我们这样的一条路径啊,或者呢,是我们说的这样一条路径。哎,说的呢,就是这个意思。啊,那我们说这个Java程序啊,咱先说Java啊,这个Java程序呢,在执行的过程当中啊,像一开始它需要执行的这个叫词法分析啊,这个语法分析,还有这个抽象语法数啊,就是我这里边这个橙色的这个过程,那这个过程啊,实际上它是由咱们的呢,哎,叫做Java c啊编译器呢来完成的。
02:01
或者呢,咱们也称为呢,叫做前端编译器,对吧?诶前端编译器,哎,我不是也这个那会儿咱们提这个词了,OK啊,那么这个过程当中最终目的呢,会形成个什么呀,就是当我们这个进行完这个叫抽象语法数之后呢,最终咱们还会去遍利这个语法数,最后呢,形成一个叫线性的字节码指令流。啊,你想想咱们看到的那个,呃,咱们通过那个jarp,呃,大家应该还记得咱们写那个程序是吧?呃,通过jarp呢,最后咱们读的那个,呃,我我我我就不具体去那个啥了哈,呃,咱们通过javap以后呢,最后生成的你那个自码文件,它其实就是个线性的过程是吧?诶从上往下意思意思打开,诶这个呢,就是咱们的一个Java c叫前端编译器的一个过程,那么生成一个自加码文件以后,接下来呢,我们要去执行程序了,这里边呢有两条路径,那一条路径呢是这个,那一条路径呢是这个。啊,那如果说呢,大家,呃,大学呢,你还学习过这个叫编译原理啊,编译原理呢,属于大学计算机系的一门基础课是吧?如果你还对这个编译原理有印象的话呢,你会发现呢,咱们这个下边这个蓝色的这一只啊,其实呢,就是传统的编译原理当中,这个程序代码到目标机器代码的一个生成过程。
03:14
啊,这个最终的目的呢,我们是生成一个叫机器代码对吧,那么中间这一只啊,实际上呢,就是一个解释执行的一个过程。啊直接呢,我们说叫逐行解释翻译执行是吧,就是这样一个过程。啊,那么对于咱们Java来讲啊,咱们说呢,叫半编译型半解释型语言,这个半解释型指的就是它,半编译型语言呢,指的就是它。诶,就是这样的一个情况,那行下边呢,你看我这就呃,咱们是网上大家也常见的这个图,这是其中的一个,这个呢,其实指的呢,就是咱们这个Java c这个前端编译器执行的一个过程,从这源代码最终呢,我们是这个使用这个叫抽象数是吧?诶然后便利这个抽象的这个语法数,最后生成的是一个线性的一个磁解码指令的一个过程。就是我们这里边这个橙色的,哎,就这样一个环节,OK,然后呢,下边这个图呢,诶,就是我们说到的后期,那我们有了自解码指令以后,咱们的Java虚拟机的这个直引引擎大注意哈,咱们刚才说的前边这个橙色的过程呢,实际上是跟我们Java虚拟机是不是没有关系啊。
04:14
那因为呢,你是在生成这个。那这个咱们找一下前面这个图。点错了哈。你呢,是不是在生成咱们这个资金码文件的时候,出现的这样的一个叫前端编译器,跟咱们的Java虚拟机呢,诶目前呢是还没有关系的。啊,还没有关系,然后这个呃,绿色的和这个蓝色的呢,才是咱们Java虚拟机呢要考虑的问题,那这里边重点提到的就是执行引擎。那下边这个就是解释执行啊,逐行呢去解释执行,上边这个呢,就是进行了一个编译的过程啊,最后呢,是生成了一个目标代码,也就是我们所谓的叫机器的指令啊,是这样的情况。行,那这个大家能不能理解这个事儿哈,那么关于这个,诶,我们说这个绿色的和这个蓝色的部分呢,咱们来说一下,哎,那个绿色呢,我们对应的叫解释的过程,这呢对应的是一个编译的过程,那这呢对应的我们就要说明一下什么叫解释器,它呢对应的就是我们说解释的过程。
05:08
啊,Interpreter是吧,那什么呢叫GI编译器啊,这呢就是我们说这个编译的过程。OK啊好,那我们先来看这个叫解释器,说当Java虚拟机启动的时候啊,首先呢,会根据预定义这个规范,对磁解码呢,采取叫逐行解释的行为啊解释的方式呢,执行将每条字节码文件中的内容都翻译成对应平台的机器指令去执行。啊就是逐条翻译啊,直接呢就执行,就直接呢就执行了啊就像我们这个呃自解码指令的时候呢,前面不都有一个呃地址是吧?然后呢,把这个地址呢存到我们这个呃PC寄存器当中,然后呢逐条呢去翻译我们后边这个指令啊去执行,这呢就是一个解释器,它的一个方式,那么除了这个解释器之外呢,我们还有一个呢,叫GI编译器。啊,我们称它叫即时编译器啊compeller,那么它呢,是将虚拟,呃是虚拟机将源代码呢,直接翻译成和本地机器平台相关的机器语言,它翻译成了一个机器语言对应的这些指令。
06:12
啊,翻译成这些指令,他没有说马上去执行是吧,它翻译成这些指令,这个过程相对来说还是比较复杂的,就是细节展开的,就是这样子的,或者我们看这个图呢也行。啊,就这样个过程是吧,那么为什么咱们Java程序呢,既要保持解释器,呃,既要保留这个解释器,又要保留这个即时编译器呢?啊实际上呢,这就是我们接下来呢,要给大家讲的这个解释器和解时偏移器的这个细节了。对吧,那至少目前呢,我们想给大家强调的一点,就是说对于咱们Java执行引擎来讲呢,它既有解释器又有编译器。啊,或者准确的说呢,咱们这个house包虚拟机是吧,大家看这呢也能看出来,这呢就是我们所谓的叫解释器,这个呢,叫其实编译器啊,那为什么说咱们这个Java语言呢,称为叫半编译型半解释性语言,主要原因呢,就是因为我们呢,诶是这个事。
07:02
诶这个有很多同学,包括我自己也是啊,这个我在一开始学习Java语言的时候呢,诶我觉得我的理解呢,就是错误的啊,当时呢,说Java语言是半编译型半解释型语言,我当时是怎么理解的呢?我是这样理解的哈,说这个Java语言啊哦,得先编译后运行是吧?后解释运行,诶它得是先通过点Java文件啊翻译成呢叫自解码文件,然后呢,自解码文件呢,在解释执行,所以说呢,叫半编译半解释行语言,哦,我自己呢,是这样来理解的啊不知道呢,这个哎,那么咱们这个同学,你现在听课的呢,你是不是也这样想,那如果你要这样想的话,那就大错特错了。那绝对不是这样子的是吧,那Java呢,叫半编译半解示性引言的主要原因,诶是因为呢,咱们这个执行引擎,也就是说再去解释执行我们的这个最起码文件,让这个CPU操作系统去执行的时候呢,我们既可以使用解释器,又可以使用呢叫解时编译器,所以呢,叫半解释型半编译型啊是这样一个原因啊,那你要是从这个历史上来讲的话呢,其实Java呢,一开始的时候呢,它其实就是一个解释执行的,或者说你把Java呢,就理解成是一个解释型的语言是没错的,因为在1.0的时候呢,咱们只有这个解释器啊,只能够去解释之行,后来的话呢,咱们才发展成为可以呢使用编译器啊,我们称为呢叫后端编译器了,对吧,这个呢,咱们叫后端编译器啊,然后呢,它可以呢。
08:23
诶,它呢可以呢,就是把我们这个自己码指令啊,层层翻译,翻译成了本地代码,那翻译成本地代码的话呢,我们就可以给他呢做一个缓存,大家还记不记得咱们前面讲的那个叫方法区啊。这个咱们就直接呢找一下啊,诶咱们讲的这个课件。呃,方法去啊。行,咱们呢,在讲这个方法区里边能存什么的时候。往上找一下,那其中呢,是不是提到说叫GI的一个代码缓存,对吧,就是我们这个通过呃即时编译器呢,它能把这个自己码指令呢,翻译成这个机器指令以后呢,能够做一个缓存,那缓存的好处呢,就是当我们如果频繁的去调用的话呢,直接我们就去调用这个呃机器指令了,那是不是执行的效率就更高了,哎,所以说呢,我们这个Java的这个程序呢,诶后来的时候呢,相当于比一开始的这个执行的效率呢,也会更高一些。
09:19
是吧,诶主要就是这个原因,那同时的话呢,我们这个翻译成这个本地机器指令的过程当中,咱们还可以不断的对这个呃磁解码指令在翻译的时候呢,进些优化,而且还可以进行这个深度的优化,这个呢也使得呢,咱们扎va程序呢,在执行的时候呢,这个效率呢也越来越高。啊也越来越高啊,那从这个角度上来讲的话呢,一开始咱们呢,总是说说这Java语言呢,跟这个C或者C加加比呢,它这个执行效率差很多是吧,那其实呢,这个Java语言发展到今天的话呢,其实它的这个执行效率呢,已经不弱于C或C加加了,啊应该这样来讲,也是由于我们这个障碍言呢,在执行引擎这块的一个呃,性能的一个提升。啊,当然呢,还有其他方面一些优良特性啊,是这样的啊行,首先呢,大家基于这个图哎,把我们这些讲的这个叫编译啊,这个解释运行啊,前期的编译啊,解释运行和后期的编译这个过程呢了解清楚。
我来说两句