00:00
那么在咱们具体往下再讲这些指令之前呢,咱们先带着大家复习一下,因为很多同学呢,对于我们上篇讲的操作站和局部变量表呢,已经有点模糊了,那这块呢,我们再稍微的复习一下操作数站和局部变量表,那从我们这个内存结构上来说呢,咱们是在当初讲这个内存的结构中的虚拟机站的时候,说这个站里边啊,我们存放的是一个一个的。呃,一个县城有一份对吧,一个一个的战针,那么每一个战针里边。一个方法对应一个战帧对吧,每个战帧里边呢,又分成具体的几个部分,那有这样的几个部分,局变量表,操作数站,剩下的我们可以统称为呢,叫真数据区啊,就是这样几个结构,然后对于一个战争里边呢,局部变压表和操作站这两个呢是最重要的结构,OK,那首先呢,我们来说一下这个操站啊,Op sta。那or呢,咱们刚才也提到这个词了,是不是叫做操作数啊,那为什么说这个结构叫操作数占呢?你现在是不是就知道了,操作数是什么意思,是不是就是对应咱们刚才这个,咱们找一个随便找一个这个代码,这个我们看一下它的这个对应的这个结构。
01:10
这个结构呢,我们看下这个扣的后边这个位置。嗯,这呃,像这个减一减二,这不就是我们说的这个操作数嘛,前面呢叫操作嘛,对吧,那把这个操作数呢,我们需要放到这个站里边,那这个站呢,我们就起了个名字就叫做操作数站。哎,其实就是这个意思啊,这是他名字的一个由来。嗯,这块你看就是一个解释,说在解释执行过程当中,每当为Java方法分配战争的时候呢,就往往开辟一块空间叫做操作站来存放计算的操作数是吧,以及返回的结果,哎,说的就是这个事情,那具体来说便是执行每一条指令之前,理解一下扎虚尼呢,要求该指令的操作数已经压入到这个操作式站当中了。你得压到这个操作数站当中,然后在执行这个指令的时候呢,Java虚拟机会将哎会将该指令所需要的操作数呢弹出,然后弹出以后呢,结合我们这个操作码,然后呢一起做一个执行,然后把这个执行的这个结果呢,再重新压入到这个站里边。
02:12
就是这样的一个意思。那为了大家更好去理解,我们下边有个图,这个图里边呢,我们是想做一个计算,计算一加二到底等于几,那一和二的话呢,我们现在把这两个数据呢,先放到我们这个操作出站当中了,这个呢是咱们的站点。就是从这个口呢,是进去的叫入站出呢也从这出,对吧,因为这个站呢是只有一个进口,进口和出口是唯一的,是这样的,像这呢,就相当于我们暂停那个位置,那我们现在呢,是把两个in的型的数据,一个叫一,一个叫二,做一个加法,所以这里边加的指令呢,我们后边也会提到,就是涉及到这个算术这个指令了,这呢叫ii的。那艾的话呢,主要是针对呢,这个占顶的这两个元素,所以这两个呢都得弹出来,弹出站之后呢,一和二做一个加法,加完的结果是三,这个三呢,还得需要再去入站,那再入站就放到我们站点位置就这个三。
03:06
嗯,那跟我们前面的这些,比如说你这个前面可能有一个或者多个等等都没关系,因为我们ii的呢,是针对于最近的两个数据,所以跟你前面这块是多少是没有关系的,这呢就是我们说的这个叫操作数占的一个概念,熟悉一下或者复习一下,咱们下边呢都要用啊,然后再一个概念呢,叫做局部变量表,我们称为呢,叫做local variable tables local variables。这个也可以翻译成叫本地变量表啊,Local翻译成局部或本本地都可以,比如说局部地区有雨啊,所以说local对吧。这个Java的方法战争的另外一个重要组成部分呢,组成部分呢就是局部变量表,它主要放的是什么呢?就是咱们当前这个方法的这次,当然前提是你是非静态的方法,静态的就没有了,放这次放入你的方法行参这些参数一个是一个的,然后以及呢,我们这个方法内部定义的这个局部变量,放的主要是这些数据。
04:04
这些数据将这个这一码程序可以将计算的这个结果缓存在我们这个局部变量表当中,OK,嗯,它就是一个数组,注意咱们这个局部变量表呢,是个数组,我们可以通过是不是指定的这个索引去找到你这个数组相应位置上这个元素吧,那我们这个操作时站着,你注意它这个占结构,它就没有所谓的这种索引之说了,你只能操作我们相应的这个占顶的这个元素,这个大家要注意,这是占和数组的一个区别。行,然后下边一个举例子,嗯,这个代码呢,也是比较典型的,嗯,举这个例子之前呢,我们先强调一下,咱们前面也说到过的,像这个四个字节,比如说in特,包括呢,Int之前的bit short char、布尔等等,他们也都是占四个字节,对于这个long和double来讲呢,他们是八个字节,那相应的就要占两个槽位。一个槽位呢,我们称为一个叫slot,是四个字节对吧?那long和double呢,要占两个槽位,那我in呢,后边如果放一个long型数据,这个long呢,它的索引位置是一,在下边放float的话呢,索引位置就是三,这个大家要注意咱们后边的一个指令当中会有这样的情况,好,那下边呢,举这个例子,这个例子的话呢,你看这是一个方法对吧?哎,是一个非静态的,那么这个方法的对应的战争的局部变量表是在这块表示的。
05:24
看看大家能不能回忆起来,首先呢,你是个非静态的,所以在索引零的位置呢,是这次当前对象对吧?好,然后呢,我们有两个参数,一个是L,一个是F,对应的类型是long和float,那这时候浪呢,我们说它是八个字节,所以呢它要占两个槽位。就是这两个槽位是一个L类型,然后呢,Float呢,它是四个字节,它就占这一个槽位就行,接下来呢,在方法内部我们有一个代码块定义这个新的变量I,那首先呢放的是I,然后这个I呢,在出了你这个大块之后呢,下边又点了一个这个代码块,那这时候I和这个S呢,它就共用这一个结构,因为你已经出了作用域了,共用这一个,这我们称为呢叫槽位的一个,是不是复用啊。
06:09
曹魏这个咱们前面讲这个上篇的时候呢,说过这个事儿,大家如果忘的话呢,你再看一看,这叫复用。好,那这块呢,大家就清楚我们这个结构便于呢,咱们下边来讲具体这些指令大家呢就能更清楚,行,最后这块呢,说的这这个两段话呢,就是也相当于咱们上篇呢也提到过,咱们说呢,与这个性能调优最为密切的就是局部变量表。为什么这么讲呢?因为局部变量表呢,我们会涉及到相关对空间的一些对象的一些引用,对吧,那我们对空间呢,又是咱们垃圾回收的一个重点区域,那也就是我们区无变量表中的这个变量呢,它就是一个GC roots。那这呢,直接关系到我们数据呢,是不是要被回收,那这个如果你要是跟局部变量表中的变量直接或间接的关联了,那就不能被回收了。就不能被回收对吧,所以它呢,是我们非常重要的一个结构啊,这个大家注意,然后方法在执行的时候呢,呃,Java这个虚拟机使用局部变量表呢,完成方法的一个传递啊,因为我们在调方法,传参数值,传实参,那你传的谁呢?是不是都是操作的我们这个局部变量表中的这些数据啊。
07:14
哎,这让大家注意行,那这呢,我们把这个操作出站和局部变量表呢,又复习了一下,那下边呢,咱们就具体看这些指令。
我来说两句