00:00
那接着啊,咱们来讲下一章,哎,下一章呢叫做执行引擎,那执行引擎这一章的话呢,这个跟咱们前面讲的这个运行时数据区呢就不一样了啊,那从我们这个扎va虚拟机整个这个架构结构上来看的话呢,我们一开始讲课的时候呢,提到过说扎va虚拟机咱们呢可以分成三层,对吧,那最上边这一层啊,叫做类加载器子系统,那这里边这个重点的话呢,应该算是有两个是吧,第一个呢,就是我们说的类的加载器啊,不同类型的类的加载器,那关于这个如何自定义类的加载器这块呢,我们到后边的时候再讲啊,然后第二个呢,就涉及到我们这个叫类的加载过程啊,涉及到呢叫loading link和initialization啊,那这个链接呢,里边又分成这三步对吧?呃,详细的我们就先不说了啊,这呢是我们前面已经讲过的,那么在这一层上的话呢,也是有相关的一些面试题了,包括呢,这个双亲委派机制是吧,这个沙箱这个机制等等,那其实呢,包括违反这个双性派机制这样的例子有没有这个呢?在大厂面试题当中也有。
01:00
这个咱们放到这个中篇的时候呢,再给大家提好,这是我们说的叫上篇哈,然后这个中篇的话呢,也是我们这个花的篇幅比较多的,这个讲的时间也比较长的,呃,这个内存结构里边,哎,这个内存分配的时候呢,非常重要的这个内存结构对吧?哎,这个呢,咱们已经讲完了啊,然后呢,在这个下层的时候呢,就会涉及到这个叫执行引擎,呃,这个执行引擎呢,就是我们这一章呢,要给大家讲解的这个内容,那相对来说呢,这一章那不管呢,是从这个面试的这个比例上来讲,相较于上层和中层它呢是最少的,那从这个具体的知识量上来讲呢,相对来说也算是最少的,但是呢,这个知识量少并不意味着说它的重要性就差,那从我们整个这个代码呢,执行的角度来看呢,这个执行引擎啊,是非常非常重要的。啊,应该这样来讲,那没有执行引擎的话呢,就没有谁能够负责,呃将我们把这个自己码文件,你只是放到内存中了是吧,你这个放在内存中的这个自解码文件,这些指令呢,怎么能够被我们的呃操作系统或者CPU呢所识别,这个呢,必须要依赖于咱们的这个执行引擎,所以说呢,它是非常重要的啊,当然这个重要呢,是从我们整个这个执行的角度来讲,那对于咱们这个学习GM这个课程呢,大家来说的话呢,那么这个执行引擎的话呢,重要性是要低于上面两层的。
02:16
啊要低于上面两层,就是我们这一块呢,可发挥的东西呢,比较少是吧?诶是这样的啊行,那咱这呢,从这样的几个角度呢,给大家讲这个课程,第一个的话呢,就是叫执行引擎的一个概述,下边呢就是关于这个Java代码编译和执行的一个过程啊这呢,其实我们也呃不完全的说涉及到叫Java代码了啊,就是说正常我们说这个不同语言编写这个代码啊,相应的都会有对应的一个编译执行的一个过程,那这呢,我们相当于是以Java代码为例呢,给大家呢做一个讲解是吧?那下边的话呢,我们就从这个语言的这个最初角度来看啊,涉及到了叫机器码,叫做指令啊,指令集包括汇编语言,包括高级语言包,包括这叫字节码是吧,这块呢,我们谈一谈啊,这呢大家作为一个了解就行啊,相当于是来拓宽你对这个,呃,咱们天天呢写的这叫高级语言了啊,图宽了你对这个语言的一个理解啊,就是偏向底层的一些概念性的东西啊,那对于咱们Java程序来讲呢,咱们一直讲叫半编译型,半解释型语言,那为什么叫半编。
03:16
一般解释性语言呢,呃,这呢就是我们提到了一个叫解释器,一个呢叫git即时编译器啊,因为这样的一个概念啊,啊也就相当于我们再去执行Java程序的时候呢,我们是有可能使用的这个叫解释器啊进行解释行的啊也有可能呢,是啊又进行了一个后期的一个编译啊,相当于把热点代码呢,进行了一个缓存啊然后呢,编译之后呢,后期我们再这个把它翻译成对应的这个机器码啊OK,是这样的行,那我们就按照这个顺序呢,首先来讲一下关于执行引擎的一个概述啊,它属于呢,我们要讲解的内存结构的这个下层啊这呢是我放的这个比较详细的一个图,那咱们下边这块不也有吗?是吧,那详细的这个图啊,就在这个结构这那这个详细这个图里边,我们想刻画呢,像这个解释器啊,这即时编译器,包括呢,这个JC啊,垃圾回收器啊,OK这呢,都属于我们这个执行引擎的这几个部分啊。
04:08
好,那首先呢,我们从宏观上呢,对这个执行引擎呢,有个理解啊,首先说到这个执行引擎是Java虚拟机核心的组成部分之一。啊,这个加了个之一啊,就让我们感觉说,哎,它是不是还不是最重号的是吧?哎,其实呢,这里边只要能加上这个之一的话呢,已经证明它是非常重要的了啊,那如果说呢,咱们说自己手手动这个,你要是写一个这个扎va虚拟机的话呢,那我们说呢,这个执行引擎它是必不可少的啊,你需要呢,写的就是主要呢,就是累加的些子系统,把它放在内存当中,然后呢,使用基因引擎的去解释执行是吧,或者呢,你再进行一个这个呃即时编译啊也可以,当然那就更复杂一些了啊,就是最起码呢,大家如果要手写一个Java虚拟机的话呢,这个累加载气子系统是吧,你得能够呃有能力把这个自己码文件呢加载到内存当中,然后呢,使用执行引擎呢,去解释执行这是最简单的了啊,内存的话呢,我们可以不画的这么复杂。
05:01
是这样的一个情况啊,OK,那再回过来啊,这呢就是我们要讲的这个结构啊,然后呢,下边一个这样的概念,首先呢,是关于虚拟机的一个描述,诶大家看一下说虚拟机啊,是一个相较于物理机的一个概念,毫无疑问是吧,虚拟机是相较于物理机的,那这两种机器啊,都有代码执行的能力,那区别是什么呀?咱们说物理机它的这个执行引擎是直接能够建立在处理器缓存和指令机上的,那指令机和操作系统上的。哎,这个是它的这样一个特点是吧,那对于我们这个虚拟机来讲啊,比如说咱们在这个Windows系统上呢,咱也可以装上一个啊,比如说Linux的一个系统是吧,这也是算是一个虚拟机啊,包括呢,咱们在这个Windows系统上,大家还可以去开发这个安卓的这个这个程序是吧,你也可以安装安装一个这个安卓的一个模拟器,诶装上一个安卓的一个操作系统啊,也是可以的啊,这呢都需要依赖于这个虚拟机啊,而虚拟机的这个执行引擎啊,它是由软件自行来实现的。啊,像我这个电脑的话呢,我不需要呢,呃,硬件上做什么样的修改,我直接呢从网上去下载相关的这个,比如watch box是吧?诶我们就可以呢,构建成一套这个呃软件层面的虚拟机了。
06:11
啊,因此的话呢,它可以不受这个物理条件的一个制约啊,限制咱们的指令集和指令引擎,因为我们知道这个指令集啊,它都是跟我们这个物理呃上的这个机器啊,它是深度绑定的啊,叉八六架构的,ARM架构的等等,它这个指令机呢,可能会千差万别是吧?啊而我们这个呃,虚拟机的话呢,它可以不受物理机的一个限制啊,执行那些不被硬件直接支持的一个指令机啊的一个格式。哎,这个是它比较好的方面啊呃,当然了,它这个执行效率来讲,跟物理机比啊,会有一些差别啊,这个大家注意一下是吧?啊,那我们这个Java虚拟机啊,其实它之所以被称为是一个叫虚拟机是吧,还是因为呢,它是由规范所定义的一个抽象的计算机啊虚拟机啊,这个我们可以把Java虚拟也就理解成是一个抽象的计算机啊就可以了。
07:00
行,那接着我们往下看啊,说呢,GM的这个主要任务是什么。啊,这要一问,那你想想GM主要任务是什么,那你这块呢,你得脑子中浮现出来,GM整个呢,它这样的三层,上层中层和下层这个结构,对吧?那主要任务的话,说白了就是把我们这个自解码文件呢,是不是加到内存中,让他解释执行啊,对吧?诶就是这样个过程啊,诶所以这里边呢,就是说主要任务啊,就负责装载自解码到其内部。啊,到期内部啊,但是咱们知道这个资金码它只是一个是不是叫跨平台的一个,呃,叫通用契约是吧?啊跨平台的一个通用契约就里边呢,比如说我们一开始呢,这个要想是一个这个什么,呃,合格的一个Java斯解码文件,哎,我们呢,得要求他是一个叫cafe baby是吧。Cafe。啊,然后baby是吧,哎,这样的一个,呃,开头这个我们称为它叫魔术,那后边的话呢,它也有严格的一个规则。啊,就是自解码呢,仅仅是一个通用契约啊,你不同的编程语言,不管是Java,只要呢,你是按照Java的这套这个这套标准,就是Java虚拟机能够识别的这个资金码啊的方式,呃,你呢,把它编译成一个合法的一个资金码,那都可以在JVM上呢进行解释执行是吧。
08:13
啊,它只是一个通用区域,诶,但是字节码呢,并不能,并不是能够直接运行在咱们所谓的这个操作系统上的,这咱都知道啊,它本身呢,是不能直接跑到这上边,咱们需要在操作系统上是不是叫构建一个虚拟机是吧?啊,因为磁解码指令它并不等同于叫本地机器指令啊,内部呢还它内部呢,包含的仅仅是一个能够被Java虚拟机所识别的自解码指令符号表啊和这个辅助信息啊,所以说咱们诶看我记得这块也有对应的一些这个图啊。诶在这是吧,诶最简单那个图,就我们这C加码文件呢,你想直接在操作系统上跑,这是不行的,操作系统是识别不了的,操作系统呢,只能够识别的就是机器指令。或者说呢,我们说笔记指令再稍微高一层叫汇编的是吧,诶操作系统是能认这个啊,诶那你必须呢,得在把这个字节码呢,得先在咱们这个虚拟机上啊进行一个翻译。
09:01
那才可以,那谁来翻译这个事儿啊,就是我们所谓的叫执行引擎。哎,注意谁来帮忙翻译这个事儿啊,执行引擎来翻译啊,翻译完以后呢,诶翻译成以后,翻译成什么呀,就翻译成我们这个操作系统能够识别的这个机器指令啊,去跑去运行就可以了,哎,这就我们所谓的这个执行引擎它的一个任务啊。那下边呢也说到了,说呢,要想让一个Java程序运行起来,执行引擎的任务,就是将自解码指令解释,或者是编译成对应平台的本地机器指令才可以。啊这呢,我是说解释或者编译,那其实呢,就对应着咱们这个啊,直接引擎的话呢,它是有这个解释器和啊其实编译器的啊,就是两种方式啊注意这个时候的编译大家整清楚,咱们这时候说的这个编译,可不是咱们一开始的时候呢这个程序,你看这个呢,是不是也叫编译对吧?诶不是说的这个编译啊,这个大家一定要注意,这个呢,咱们称为呢叫前端编译,那当我们有了这个字解码以后,咱们呢,在这个对应的虚拟机当中啊,通过一个东西,然后呢,把它翻译成机器指令去执行这个东西呢,我们就称为叫执行引擎。
10:08
啊叫执行引擎,这个执行引擎这块呢,它又分成了两种行为,一种行为呢叫做解释执行,一种行为呢又叫做编译,那这个编译呢,咱们称为呢叫后端编译,就跟说咱们开发呢有前端有后端一样是吧?哎,这个呢称为叫前端编译啊,就是在前边这个编译的这个过程啊,就是一前一后,这个大家一定要区分开啊,这个是咱们这里边说的这个变异啊,可不是说的那个生成磁解码的时候那个变异的过程。啊,这要注意说简单来说啊,咱们这个Java虚拟机的执行引擎啊,就充当了高级语言翻译成机器语言的一个翻译者,或者叫翻译官。对吧,诶,那这儿呢,我也发了一个图,哎,这从网上找了一个图片哈,这个现在呢,这个特朗普,哎这个非常火是吧,疫情期间呢,这个天天露面哈,这个有时候想想也挺奇怪哈,只有美国好像是这个总统天天开发布会,天天这个大记者问啊,而且呢,这表现呢,确实是天天上头条啊,就是他的这个黑料呢,你都都都报不完啊行,那比如说呢,咱们现在就以这张图为例,这个。
11:12
川普啊,这是这个这个美国总统现在呢,跟这个韩国总统呢,现在要进行一个会面交谈,那美国呢是说英语啊,韩国呢是说韩语。啊,说韩语是吧,哎,那么这两个不同语言的这个人呢,进行交流的时候呢,哎,比如说这个特朗普呢,现在说一些英语,说完以后呢,这个,诶这个韩国总统听不懂是吧?诶文在寅听不懂,那听不懂怎么办呀,这时候我们就需要中间有个翻译官。那需要翻译官,那么这个时候呢,咱们可以认为这个特朗普啊,它代表的就叫做自解码,或者呢,咱们泛泛的称为呢,就是Java应用程序啊都可以啊,都可以准确的说呢,其实就是自解码,因为已经是过了咱们前期的这个编译的过程是吧?啊已经到这儿了啊,行啊,那么我们这个自检码呢,你要想直接在这个操作系统上去跑啊,跑不了操作系统上就是文在寅啊,这个特朗普说完话他听不懂啊,需要呢,经过这个翻译翻译一下,那翻译是谁啊,翻译啊就是咱们说的叫执行引擎,那从这个角度上来讲,这个执行引擎是不是非常的重要啊,你没有它的话呢,这个操作系统根本就不知道你想干什么,那你这个代码呢,是不是也就白写了?
12:19
哎,特朗普白说了啊,翻译呢,没翻译是吧,这个文字听不懂啊,就废了。那就成这样是吧,哎,那我们说这个翻译啊,其实从咱们这个,呃,工作上来讲,是不是也是一个非常高级的一个工作,对吧。呃,大家能认可这个事儿吧,我记得呢,当我上大学的时候呢,在个零几年,嗯,我想想啊,应该是0506的时候,零六左右吧,哎,那个时候呢,我还在上大学,然后呢,学校呢有一个讲座我就去听了,当时呢,我是在长春上大学是吧,然后呢,这个北京的一个是做翻译的这样一个培训学校呢,就过去做讲座了啊讲的挺好的,但是当时我印象很深的就是他画了个饼图啊,首先呢,他给我们提到两个事儿啊,第一个呢,就是这个翻译,尤其是同声传译啊,待遇非常高是吧,按按,呃,准确的说就可以按秒去计算工资的是吧?呃,薪资呢非常诱人啊,那其次的话呢,说这个能够达到同声传译这个水平的啊,画了一个饼图啊,你可能是有1万个人里边呢,可能就这么几个人,哎,能够达到这个同声传译的水平。
13:21
啊,这个绝对是机灵中的机灵啊,也确实是这样啊,这个我也认识一个呃朋友,然后他就是做这个翻译的。啊,就是他们这个对学历的要求其实也蛮高的,那他的这个英国的老师呢,还是专门给这个伊丽莎白这个女皇,但女王做翻译的啊,还是挺厉害的啊嗯,这个他们待遇呢,其实是挺高的啊,但是呢,现在呢,咱们知道随着这个AI的一个崛起哈,这个翻译的这个行当呢,其实挺尴尬的是吧?啊就是一般的这种翻译啊,其实我们都可以完全的被AI去替代啊,语音识别是吧,这个语音翻译行啊很尴尬啊,随着AI的一个崛起,包括呢,国家现在又弹出这个,呃,40几万亿的这样一个基建项目啊,那其中呢,像AI啊,大数据啊,5G啊,呃,这都是属于政府呢要重点复制的这些行业啊,那么这块呢,大家也诶多想一想,这个未来自己的一个发展是吧。
14:15
OK,那咱们这个拉回来啊,那这里边这个翻译官呢,它就相当于是我们的叫这个直引引擎啊,那通过这个呢,大家能够非常清晰的能够知道啊,这个直引擎为什么说它非常重要啊,一谈到指引擎,你得能够知道这个事儿啊,他呢就负责将自节码呢翻译成操作系统能够识别的机器指令来执行的,所以呢,非常重要啊,那接着呢,咱们再从另外一个角度来看一下这个直引引擎的一个工作过程啊,这个图的话呢,除了我把这个我我要把这个直引引擎拿走了,大家应该并不陌生是吧,就是这呢,就是我们这一个战里边呢,是不同的战帧,嗯,战帧里边的几个部分结构,那PC计算器里边呢,就是记录了我们当前这个战帧里边你一个方法呢,是不是,呃,这个相应的一些这个操作是吧,哎说到这儿的话呢,咱们就可以拿之前讲的这个方法区。
15:04
咱们不是最后的时候呢,举了个例子嘛,咱们还拿这个例子可以来说一下。OK,就这是吧,诶针对咱们写的这个may方法里边的这样的几行代码,然后呢,咱们使用这个扎P呢进行一个反编译是吧,你就能看到啊,是这样的一些这个操作啊,这呢就是一些,呃,你要主机符也行,操作符是吧,然后它底层对应的就是一些自解码指令了啊好,那这呢,就是我们刚才呢,上面这几行代码对应的这样的一些操作,诶那么左边这些序号呢,就是我们在执行的过程当中啊,你所要记录的这个,呃,算是地址,这个地址呢,就存放在我们这条程序记录器里边。OK,没问题是吧?行,嗯,那么呃,在这个执行的过程当中,我们说呢,你要是有对象的创建呢,我们就在这个堆序里边去放,然后对序里边呢,我们是不是也记住了一个类型指针指向了我们这个方法区啊,你这个类元数据这个咱们在讲这个方法区的时候呢,都讲过这个事是吧。哎,我们那是不是还画了一个对应的图。
16:00
哎,咱那个图,嗯,画的是是这个图啊,应该还能记得是吧?好,那在这个过程当中,我们说这个直行引擎,它扮演的这个角色是什么呀?诶这个直行引擎的话呢,其实呢,就是去执行我们相应的这样的一行一行的这个代码。哎,就是执行我们这样的一行行列代码,所以呢,它主要呢,就是从我们这个程序计数器里边所代表这个地址去取相关的一个指令,这个指令的话呢,对应的是我们这个操作数,你看我们这个操作数呢,不断的去操作,哎不断的是这个变化是吧?哎,那这个指引引擎呢,主要负责的就是这个叫什么程序计数器所代表的这个地址,整个呢,哎,来处理我们这个比如说局部变量表,包括操作入站啊这样的一个执行过程,那这个时候呢,我们这个操作入站啊,它不断的进行出站和入站啊,它呢就起到一个信息交换的一个作用。啊,就这样子的啊,那直行引擎呢,主要面对的就是我们这里边的这个叫站在里边一系列的一个操作。行这块呢,你看我也写了几个信息啊,说执行引擎在执行的过程当中,究竟需要执行什么样的自行码指令,完全呢依赖于PC寄存器啊,因为咱们是从这个里边取的那个地址,看看那个指令是啥的,对吧。
17:09
然后每当呢,执行完一项指令之后啊,诶PC寄存器呢,就会更新下一条指令啊,这个呢是很显然的问题啊,再接着呢,就是执行引擎呢,可能会通过存储在局部变量表中的这个变量,哎,这个对象的引用准确的定位到存储在对空间中的这个对象实例。啊,以及呢,通过对象图中呢,叫原数据指针啊,这个我们叫类型指针是吧,然后再定位到我们这个目标对象的类型信息啊,就指向了这个方法去啊,实际上说的是呢,是不是就是我们这个问题啊。哎,就是我们这个直引引擎,通过这个局部变量表中,它就找到对空间中的这个结构了,离形值呢又指向它,哎就是说的这个过程,哎,那这个直引引擎啊,就负责呢,是不是就翻译我们这些呃自解码指令啊,然后呢,把它翻译成对应的这个机器指令,哎让我们这个程序呢,哎操作系统呢,哎去执行啊,包括你这里边我们做个加的运算,是一开始是50跟五做一个加的运算,这呢需要调用到CPU。
18:07
对吧,哎,那CPU怎么能识别啊,就是由于我们这个指引引擎去把它呢,做了一个翻译,来翻译成对应的这个机器指令啊,来做的这个事啊行,那通过这样两个角度呢,给大家来说明了一下,诶大家对直行引擎的一个理解。啊,一个理解。行啊,最后呢,你看我这呢,又写了一句话啊,从外观上来看呢,所有的Java虚拟的执行引擎输入输出都是一致的,哎,输入的是自解码的二进制流,那处理的过程呢,就是解析啊,或叫解释执行,当然呢,还有一个叫编译的一个情况。啊,输出呢,就是一个执行结果。OK啊,那整个这块呢,大家能清楚就可以了。
我来说两句