00:00
好,那上一节啊,咱们是说清楚了,在何种情况下呀,咱们会触发这叫git编译器,对吧?诶这个呢,咱们已经说清楚了,那接着呢,咱们来看下个问题哈,那对于这个house虚拟机来说啊,大家都知道呢,咱们说是默认情况下呢,是一种,呃,这个叫节释器和接器呢,其实编译器呢,是混合使用的一种模式,对吧?当然了,我们这里边也可以通过相应的这个参数呢,设置一下,改成了我们让这个house包虚拟机只使用解释器的模式,或者呢,是只使用这个JT编译器的模式,当然呢,你也可以去,诶设置呢,它就是一个混合模式,那这个呢,是都是OK啊可以实现的,那首先呢,咱们从这个命令行的方式呢,给大家举个例子啊,诶V2,然后我们呢,CMD调进来,那默认情况下呢,我们这样来查看的时候,那这时候呢,大家看到其实就是我们叫混合的一种模式,对吧?I mix mode啊,然后呢,我们可以通过这样的方式来设置啊,杠X,这让我写一个int,然后呢再去这个杠沃,那此时呢,我们这就切换成是一个纯。
01:00
解释器的一个模式,哎,纯解释器的一个模式啊,那么就是诶我们这个解释器呢,叫interpreter interpreter,是吧,然后这呢叫interpreted mode,就是解释器的一种模式,那如果呢,我们想切换成是一个纯编译器的一个模式哈,就是我们所有的代码呢,上来呢,都必须让他呢去,诶这个直接呢编译成这个机器码,然后呢再去执行来杠X,然后看cup是吧,这就可以了啊compeller嘛,嗯,然后呢,这是一个version。那这呢,就是一个compel的这样的一个mode。那这呢,就是我们说这叫诶编译的一种模式啊,就是纯这个编译的一种模式,然后呢,你也可以呢使用再给它修改成啊叫mix是吧?哎卧室这呢,又改成了我们这个叫混合的一种模式,行这呢给大家做一个演示,就是我们在命令行的时候呢,诶该如何呢去做一个切换,那这是一种情况啊,那么另外的话呢,咱们在开发当中呢,大家实际上呢,是不是可以直接在我们这个代码当中呢,进行一个设置,对吧?这也是可以的,因为它本身就是我们GM的运行参数嘛,OK是吧,那这呢,我写了一个这个代码。
02:07
看我写这个代码,嗯,大家来看一下啊,这个代码是这样的,我这呢定义了一个方法,这个方法呢是一个count count是主要来控制我们这个循环的便利的一个次数的,哎,变了一个次数行,那下边的话呢,我们是有一个这个for循环。哎,在这个负号循环里边呢,我这是写了一个,嗯,从二开始啊到100,这是二到100这个质数的一个计算啊,这里边呢,我并没有去输出啊,没有必要,咱们主要呢,就把这呢当成是一段代码,然后我让这段代码执行了,诶是不是这个COUNT4是吧?诶执行COUNT4,然后呢,在这里边我们去判断一下这个执行这个方法的话呢,我这设置了一个值是100万次,那执行100万次呢,我们看花费的这个时间是多少。那咱们在前面呢,也提到过了,在相应不同的这个版本当中,哎,我们这个呢,把它呢,是不是编译成这个,使用这个git进行编译的话呢,它的这个呃,次数呢不一样,在这个serve word的这个模式下呢,是默认的是1万次,那咱们默认情况下呢,咱用的这像64位的操作系统,它就是一个serve。
03:13
啊,64位操作系统,它就是个server的啊行,那么在这种情况下呢,咱们设置的是100万次,那这样的话呢,肯定是我们会考虑呢,把这个就是默认情况下啊,咱们会考虑呢,把咱们相应的这个方法呢,在调用的时候呢,会有一个呢叫呃判断它为热点代码,然后呢,进行一个提前的一个编译的过程是吧,当然前期呢,会有一个解释执行的这样一个环节,那我们这呢,可以把它呢改一改,改完以后呢,咱们来看一下纯用解释器和纯用这个诶编译器的方式,我们看看它这个执行的时间呢差多少。行,那这呢,咱们打开这个run是吧,找到我们这个叫editit,那I呢,找到我们当前这个程序啊没问题,行,那这个情况呢,我们直接呢在杠X先呢,咱们就写一个叫int,这就是纯解释器的一种方式。
04:00
此时呢,我们把它执行起来。哎,这呢,我们是100万次啊,还是需要花一点时间的,呃,这个6520毫秒,诶这样咱们就记录到这儿啊,诶这么多这个毫秒,然后呢,咱们给它改成是这个叫纯这个编译器的一种模式啊,纯编译器的模式OK修改。嗯,跑一下我们再执行啊,大家会发现呢,这一秒钟都不到是吧,当然这里边呢,有同学可能也会想啊,说你这个提前的话,那个程序呢,经过这个内存一个执行,那你再执行的话呢,有可能时间本身就会小一些,那大家呢,可以多执行几次,求一个这个平均值啊,这也是可以的啊,我这呢就呃不这样去执行了,那明显呢,他们这个插出来这个数量级了,所以呢,就是即使呢,你先跑这个编译的模式,再跑我们这个解释器的模式呢,其实这个时间也能插出来啊,大不了咱们就现在再跑一次这个解释器的一个行模式呗,对吧,比如说大家呢,在这块呢,再来一个叫int吧。
05:09
找一下。你看这一秒钟之内肯定是没出来对吧。也就是说呢,你看还是这个六毛多啊,也就是说呢,这个我们纯用这个解释器的模式啊,确实呢是要慢一些,这也是咱们这个Java呢,在这个JDK1.0的时候呢,咱们采用的一种模式,那确实呢,这个时候你要看跟咱们现在的这个Java,呃,这个去让程序运行相比呢,这个差出来这个数量级了啊是吧,有一些这个差距啊,那顺便呢,咱们再测一下这种混合模式,看看这个效果如何。跑一下。嗯,那大家呢,看到我们这里边花的时间呢,也不多啊,这个936毫秒是吧,就是跟我们这个纯用这个编译器的模式啊,差不太多啊,差不太多啊,行,嗯,为什么会有这样情况呢?因为本身呢,你像咱们这个次数比较多了,在一开始这个一万四之内的时候呢,我们用的是这个解释器,那后边啊,你像这个我们是1万,然后现在呢,咱们是这个叫100万是吧,相当于1%的情况呢,咱们用的是这个解释器来执行的,99%呢,用的都是这个编译器,所以呢,他们两个呢,你看,嗯,确实呢,看不出太大的区别,但你要说这个mix方式确实小一些,那因为呢,咱们一开始的时候呢,用的是解释器嘛。
06:31
那解释器的时候呢,就不像你这个纯用编译器,那一开始的1%的时候呢,是不是还稍微延迟了一点是吧,它有一个这个响应时间,它要慢一些,那mix呢要快一点是吧,这是我们细微的去讲这个事,但是呢,因为咱们这个本身这个CPU在执行的时候呢,他有不断的去切换不同的这个进程,所以呢,单纯的这块我们去看这个差这个十几毫秒的话呢,其实不是特别明显,那大家可以把这个数据呢,你再去做个调整,诶再去试一试是吧,诶至少呢,我们通过这个数据呢,能够说明咱们的问题就可以了,行这呢就是指的是咱们虽然说叫这个housewa这个虚拟机,我们有这个,诶默认情况下是混合模式,但是呢,我们还可以专门呢去把它设置成只用解释器,还是说呢,只用这个git编译器。
07:14
OK啊,这就清楚了啊,其实默认的话呢,咱们通常就不用改了啊,这个大家用这个混合模式不是更好吗?是这意思吧。啊,这意思啊,行好这个呢,说清楚以后呢,咱们接着呢,再给大家说一下这个模式的问题,刚才呢,咱们在这个命令行的时候呢,其实已经看到了,这是有这个叫server是吧,就是咱们64位操作系统,实际上呢,它默认情况下呢,就是server的一种模式,哎,就是server种模式,那这里边写到的说housework虚拟机呢,它实际上内置了两个git编译器。哎,那是两个git编辑器,也就我们要从这个角度来看的话呢,这还得再分出来一个差。说呢,刚才呢,提到说可以显示器可以这个编译器也可以混合用,现在这个编译器这块呢,我们说有俩一个呢,叫做C1,一个叫C2,那C1C2的话呢,是我们一个简单叫法,那也可以称为呢,叫客户端的一个啊,这个comp啊,还有一个叫server的一个comp。
08:08
那就是一个呢叫C1,一个叫C2啊C1呢就是client啊,C2呢就是我们这个server,嗯,咱们呢可以通过使用这个指令叫杠client和杠server呢进行一个选择来进行一个选择,注意这块呢,呃,对于我的这个电脑来讲,是没办法进行选择了啊,因为我电脑是64位的操作系统啊,大家在这呢,自己的电脑上也都能看得到。那64位操作系统是吧,哎,当你是64位操作系统的时候啊,你的这个相应的这个JDK的环境呢,就是认为是server。啊,就是认为是所有的啊,这个呢,也不是我说的是咱们这个,诶GM这个参数官方呢,就说到这个事情了,咱们找一下这个参数列表。打开了是吧,然后呢,CTRLF我们去搜一下啊杠,咱们先搜一下这个server吧。可以了是吧,Server你看这写的啊,它它呢是来设置我们这个server的这一个参数的,嗯,64位的一个版本,就是JDK呢,你是64位一个版本的,它就支持咱们这叫呃,Server。
09:05
那它呢,就不用你再去设置了啊呃,那64位JDKJDK呢,咱们是在64位的操作系统上去安装的,它们是一一对应的关系是吧?诶所以这里边呢,我们这个呢,就不用刻意指定,而我们再去看一下这个叫杠client。OK出来了,说呢,这也是设置我们这个呃,客户端的这样的一个呃模式啊,说64位的一个版本,当你这个JDK是64位版本的时候呢,它呢就会这个参数你设置成它呢,就会被忽略掉啊,因为呢,它使用的就是这个serve,那写的也非常清楚,OK,那对于大家来讲啊,就是现在呢,咱们主流的这个操作系统呢,都是64位的了。对吧,都是64维的,那接着呢,我们安装的JDK,包括各种软件呢,也都是64维的,所以说默认的时候呢,咱们用的其实就是这个杠四这样一种模式啊,那这两种编译器的区别是什么呀。区别的话呢,简单来说就是这个C呢,它的优化呢,稍微的呃弱一些是吧,哎,我们这个杠四呢,就是优化呢,更深度一些,或者叫更激进一些。
10:05
啊是这样是这样子的。那就好比是咱们说这个编译那会儿提到写信呢,就好比是你请这个比较尊贵的这个客人是吧?哎,吃饭的时候呢,这个日信呢,就是很快就能上来,就是这个,诶大餐之前的几个甜点是吧,几个小凉菜啊,然后呢,这个烤鸭呢,就好比是咱们说的这个大餐啊,就是隔了一点时间呢,上上来的,有点像是经过这个编译器,哎,我们编译以后的这个机器指令一样啊,那么在这里边呢,说你这个烤鸭有两种做法啊,一种呢,花的时间呢,稍微短一些是吧,哎,口味呢也不错,哎但是呢,这个呃,比如说这个20分钟就能做好,那另外一种呢,就是诶你可以等的时间啊,稍微的再长一些,比如咱们需要等30分钟,哎,这里边我给你做的这个工序啊,更多,哎这个咱这呢叫优化呢,更激进是吧,哎更深入,那这个呢,你说烤鸭的这个步骤呢,相当于是越多,那刚刚口味呢就越好。嗯,就是你花的时间多,这两种方式呢,你要真正吃的时候,肯定是这个花的时间多的,这个这个工序多的,这个肯定是更好吃一些,对吧,也就是说呢,呃,你不管你是用这个client模式还是这个所有模式,你要是用了这个所有模式了,那肯定这个所有模式得到的这个机器指令呢,它的执行效率肯定是更高的。
11:16
啊,但是他的问题是什么呀,就是他花的时间呢,是要更长一些啊,我们说任何事物呢,是不是都有两方面是辩证的是吧,那马克思不也讲了这个点嘛,辩证思维是吧,就是这个辩证思维还是非常牛的一种这个思维方式啊,就是他不说任何东西是绝对的是吧,这个这个诶,任何东西它有好的有坏的啊,有有好的方面,也有坏的方面,也有有利的方面,也有美丽的方面啊,其实世间万物呢,也确实是这样子,是吧,很难有这种绝对的一种情况啊。那这呢也是一样的道理,那如果说你想想,那要是这个server端各方面都比这个可兰端要好,那我们就没有必要再去有这个可兰是吧,那既然呢,它有两种,那肯定是他们各自的这个优势啊,是一种互补的关系,耗时短啊,当然呢,这个优化的这个呃,耗时短是它的好处啊,那优化的就稍微差点意思,那你这个server呢,就是耗时比较长啊,比较激进是吧?哎,那但是呢,就是你一旦要使用它的话呢,它这个效果效率啊是更高一些。
12:10
啊,那么他们分别呢,是从哪几个角度呢来进行优化的呢?我们先来看这个啊,这个C就是我们说这个client方式呢,它主要叫方法内联,去虚拟化和勇于消除。哎,方法内点就是我们将引用这个函数代码呢,编译到这个引用点处,就是我们不是说一个战帧,呃,这个对应一个方法了,我们直接呢,相当于把这个方法呢,给它融合到一起了,减少这个战争的生成,诶挺好是吧?诶去虚拟化呢,是对唯一的一个实现类,比如我们接口也好,还是说这个抽象类也好,它有这个实现类,你要是就一个的话呢,诶我们也不用这种这个去过多的这个去关联了,是吧,就当成它唯一的时间类也可以呢,进行一个融合,那容易消除呢,就是将一些不执行的代码呢,进行一个折叠,哎,就是比较轻量级的一个优化。啊,轻量级优化,而这个CR优化就是我们说在这个server方式上,它的一个优化呢,叫标量替换,叫站上分配,叫同步消除,那说到这儿呢,大家是不是感觉有点眼熟啊。
13:08
对吧,咱们在讲堆的时候呢,最后提到了说,诶我们创建的对象一定要放在堆当中吗?当时咱们就提到这样叫标量替换,占上分配和这个叫同步消除,它的基于的前提呢,是不是叫逃逸分析啊。诶,这三种情况只有在咱们这个叫server模式下呢,才会被使用,诶才会被使用啊,那默认的时候呢,咱们就是server的,所以当时呢,我没有刻意的去强调这样一个参数啊,你像我64位操作系统注意,诶我现在呢,我也改不成是client模式啊,就是一个server模式是吧,那就意味着是不是我们就一定只能是用这个C2C1这块就没戏了呀,其实也不是,就是C1呢,是不是我们就不实行了,其实也不是,所以这块又涉及到叫分层编译的一个策略。啊,这个事还是比较多是吧?哎,都是一些概念性的啊,什么叫分层编译策略呢?说这个程序在解释执行的时候呢,诶如果你要不开启这个性能监控呢,是可以触发这个C1的,哎,那进行一些简单的优化,那你要加上这个性能监控呢,诶我们就可以去触发这个C2,进行一个激进的优化,包括呢,你这个机器优化的过程当中,如果说这个失败了,哎,我们还可以再退回程用解释器进行执行。
14:17
啊,进行解释器执行啊,呃,多说一句啊,就咱们这个C2这个,呃,编译器的话呢,JT编器,它是用这个C加加来编写的啊,C加来编写啊。行,那么回过来,那么对于咱们JDK7之后的这个版本,咱们呢,因为已经默认的就是这个杠server的一个模式了,诶在这种模式下呢,它默认的就开启了叫分层编译的策略,呃,也就是说呢,咱们这个还是可能要用到这个C编译器的。是吧,还是要用到它的啊,就是不开启行能监控的话呢,我们就用C1啊,你要是开启的话,我们就考虑是用这个C2,哎他们俩实际上也是一个协作模式,也就是说呢,我们这里边儿的这些策略呢,是都有可能哎参与进来的。啊能理解是吧,哎,这个呢,整个其实大家做一个了解就行啊啊那后边呢,我们做个总结说一般来讲啊,GI编译出来的机器码的性能比解释器高,哎,咱们已经很清楚了啊然后这个呃,C2编译器呢,就针对这个编译来讲的话呢,C2编译器呢,又比这个C1呢,这个执行速度要快,当然呢,缺点呢,就是执行的要慢一些。
15:17
OK啊,行,这就过了。
我来说两句