00:00
行,那接着呢,咱们来给大家说第三个概念啊,这个概念呢,叫做stop the word,这个呢,在咱们前面讲这个内存的时候,讲这个垃圾回收这个算法的时候呢,实际上呢,我们已经诶提到过这样的一种场景啊,就叫做stop the world啊直译过来呢,就是停掉全世界是吧?哎就这样意思,他呢主要指的就是在咱们这个整个应用程序在执行的过程当中,对吧?呃,整个应用程序执行过程当中,一旦呢,我们发生这个JC事件的时候啊,这个时候呢,会使得我们整个应用程序呢停顿下来,当然这里边我们所谓的这个应用程序呢,主要呢,指的是这个用户线程,就是咱们呢,写了一个程序对应的这些线程,让他们停下来,那这个停下来的这个行为,我们就称为叫做stop the word简写呢就叫STW,那以后呢,大家就能知道这个事了啊,那由于呢,咱们把整个应用程序这个线程都给停下来了,那整个应用程序呢,就没有任何的响应,有点呢像卡死的状态,那就是有点像卡死的状态,就这样的一个情况是吧,哎,就叫STW。
01:00
行,那么哪些场景下我们需要做这个事儿呢?那大家想想,我们在进行GC这个垃圾回收的时候呢,我们需要使用相关这个算法,对吧?那其中呢,我们说需要呢,这个使用因这个叫什么可达性分析算法啊,去枚举这个根节点,那么这个根节点啊,咱们知道这个程序呢,在执行的过程当中,它是可能随时在变化的。诶,它是可能随时变化的,这个大家还记得咱们之前讲这个程序的时候呢,在上一章对吧?诶咱们讲到这个叫GC,这个roots,关于它这个代码描述的时候呢,我们这个代码量说并不大,当时呢,咱们是不是生成了这样的两个这个大MP文件对吧?应该大家还有印象生成两个大文件,然后的话呢,我们使用这个叫MAT呢,把它呢去加载一下,这呢我再去打开。那再去回忆一下。行,然后呢,我们选择这个叫file,很open,找到咱们桌面上的。那这个大文件这呢,我们就再随便挑一个。行加载出来了,然后呢,在这个位置呢,我们去找这个叫Java basics,然后这呢叫j c root,那这里边我们可以看到当前咱们这个代码量并不大的情况下呢,这个程序当中就有1700个,这个叫这些root对吧?当然这个呢,也是在咱们运行过程当中的某一个瞬间,咱们看到的是有1700个,然后呢,我们当时程序呢,通过这个scanner,咱们不是稍微停顿了一下吗?如果我们再去打开另外一个的话呢,你会发现呢,这个jc root啊,它的个数呢会不一样。
02:24
哎,我们再来看一下,你看是不是有变化呀,对吧?啊是有变化的行,那就意味着咱们这个程序呢,在执行的过程当中,这个jc root呀,它这个个数啊,个数包括具体的是哪些叫GC root,它是在不断变化的,那么我们要想进行垃圾回收,咱们说了,最初呢,你得先确认啊,哪些是J些root,然后呢,通过这叫可达性分析算法,我们找到你关联的这些对象,是吧?啊,那你该做标记,做标记啊是这样一个行为,那么这时候呢,我们说你要想进行垃圾回收,你需要呢,保证咱们这个数据啊,在某一刻呢,你不能再动了。
03:00
就是用户线上你得停下来,在这一刻呢,我们去确认一下当前的j c root,所以说呢,这块写的就是分析工作呢,必须确保在呃,必须在一个能够确保一致性的这个快照当中进行。那一致性呢,是整个分析期间,整个执行系统呢,看起来呢,就像冻结在某个时间点上啊才可以,那如果说我们不这样做的话呢,就可能导致这个对象的引用关系啊不断的在变化,那你这个分析结果呢,肯定就不对了,那现在呢,这一刻它还是个这些图的下课呢,它已经回收掉了,那你在这些的时候呢,你到底回不回收这一支上对应的这些数据呢?是吧,哎,这都是问题,所以呢,简单来说就是一句话,确保数据的一致性,哎这个大家注意啊,那举生活中的例子呢,就有有点像比如说这个警察在办案的时候啊,说现在呢,发生一起这个交通事故啊,或者说这个严重的这个凶杀事故,是吧,那现在的话呢,警察,警察就往这一站说,现在所有人都停下来,都不要动,然后呢,诶,我一点点的去排查这里边的每一个细节,你不能在这个案发现场呢,大家每个人还该干什么干什么,那这个案件就没法判断了。
04:05
对吧,诶是这样子的,再包括呢,就是大家呢,这个比如说打扫屋子也是一样啊,比如说你老妈呢是打扫屋子的,然后呢,他需要判断说哪些东西呢是垃圾,哪些需要清理,在他呢进行判断的这个过程当中,你呢不能再去造垃圾了,你也得先停下来,然后呢,诶这个让家里边这个老妈呢,先先走一遍是吧,看看哪些呢需要去清理,那如果说他在这块判断的时候呢,你这块还扔着,那这个呢,一致性呢就不能保证了。那这这个要注意一下啊。行,这个呢,就是我们所说的这个STW,它呢,呃,它的产生的一个原因是吧,在什么情况下会出现,那下个我们要说的就是它是一定要发生的。对,它是一定要发生的啊呃,被HTW中断的应用程序呢,这个线程会在完成GC之后呢进行恢复啊,频繁的这个中断,频繁的中断呢,会让用户感觉到这个网速呢不快啊,造成的电影呢像卡顿一样,所以呢,我们尽量要减少这个STW这个发生。
05:00
嗯,就是每次我们进行GC的时候呢,这时候我们说都会出现这个叫ITW,所以尽量的我们是不是这个GC的频率呢,就不要那么高是吧?诶这个意思啊行,那下个问题呢,就提到了说ITW这个事件呢,跟采用哪一种垃圾回收器啊没有关系,因为所有的垃圾回收器都有这个事件。诶都有这个事件,那我们后边呢,下一章讲这个垃圾回收器,会提到第一款叫这个并发性的垃圾回收器呢,叫CMS啊叫CMS,这个CMS呢,虽然号称它是一个低延迟的,但是呢,它也不能够避免不出现STW对吧?包括呢,我们现在当前JDK默认的叫g first垃圾回收器,它也不能避免这个STW的发生,包括呢,咱们后边还要提一个比较新的呢,叫ZJC,包括呢叫新豆啊啊JC等等,他们呢都不能够保证STW这个事件呢不发生。反过来说呢,就是全部都会发生,只能说呢,垃圾回收器越来越优秀,那回收的效率呢越来越高,我们尽可能的缩短了暂停时间。
06:05
也就是说我们这个ITW的时间,包括它发生的一个频率。啊,包括呢,时至今日,咱们说衡量一款垃圾收集器,我们主要的参照标准呢,就是呃,当然一个呢叫吞吐量啊,另外一个呢,就叫低延迟,或者也称为呢叫暂停时间,现在呢,呃主流的我们更关注这个暂停的时间,就是给用户呢一个比较良好的体验啊就是你想要时间呢,得得OK是吧?诶就是这个问题,诶但是呢,大家都不能保证说这个事儿不发生,只能说呢,我们尽量让这个时间呢,诶这个控制在一个可以接受的范围之内。啊,可以接受的范围之内,那就可以了,那下一章当中咱们具体的去说这个情况。啊OK行,那下边的话呢,说STW呢,是张亚旭你在后台呢,自动发起和自动完成的,那就这块呢,用不了,我们说诶咱们让它发声,咱不让它发生,这个你不用了,因为JC呢,通常我们说都是自动的垃圾回收了,所以这个事件呢,它也是自动的去发生啊在用户呢,不可见的情况下呢,就执行了,嗯,那么当咱们呢,要是显示的通过system.jc调用的时候,咱知道呢,咱们调system.jc会触发那个for jc对吧?诶for GC的话呢,就会产生这叫stop word这样一个行为,这咱都知道了,所以在开发当中,咱们一般呢,啊,咱也不会去主动的去,诶回收这个垃圾,调用这个G些这个行为啊,咱们只是在一些测试,包括呢,那个性能基准测试的时候呢,咱们说过,咱们才会去主动的调一下这个GC显示的去进行一次垃圾回收,对吧?哎,这个问题啊。
07:31
行,那么这呢,我也写了个代码,让大家呢去体会一下,说所谓的这个,那stop the word这样一个行为,哎,你看我这个代码呢,这个设计的还是比较巧妙的啊,我这样来做的,嗯,这呢,我是提供了一个线程,然后下边呢是另外一个线程,我们先看下边的一个线程,这个线程呢,做的事呢,就比较纯粹了啊,我们先记录一个当前系统的时间,然后呢,在外处里边呢,这个那不断的去获取一个新的时间,这个新的时间的话呢,我们看这啊,每次呢,让他执行的时候,就是我们执行这个c cell的时候呢,都会让它停顿上一秒钟。
08:04
那都会停留上一秒钟,因为我们这也没有其他额外的更耗时的这个操作了啊,所以基本上就是每隔一秒钟它就会打印一次。啊,下边呢,就是我们这个线程的一个启动行,这呢,针对咱这叫print thread这样的一个线程,针对它,咱们先把上边这个线程呢,我暂时给它关掉啊,咱们先跑一下这个程序。行,这就跑起来了,跑起来以后呢,大家你会发现呢,咱们当前这个程序,你看基本上是不是就一秒钟打一下啊。就是很规律性的一秒钟打一下,因为呢,咱们是每隔一秒钟让他做一个sleep。行这块我就停掉了,然后呢,咱们来看上边这个线程,上边的线程,上面的线程我是这样来处理的,我这呢提供了一个叫a list,然后在这个well处里边啊,每隔这个1000个的时候呢,呃,就是循环这个1000次,我们把它加到这个list当中啊加进去,当然这个呢,加加完一遍之后呢,看一下这个size够不够1万是吧,超没超过1万没超过的话呢,我们再再跑一次这个for循环,看就是这样子的对吧?哎,当你超过这1万这个数的时候呢,我们例子都clear clear的话呢,就把它这个例子当中的所有的这个存储的数据呢,是不是都就清掉了是吧,就断开这个连接了,然后这块呢,你看我显示的使用了叫JC是吧,c.JC咱们在前面呢,已经讲过c.JC这个方法了,哎,这个呢我们就会啊触发是不是我们说这个叫for GC操作呀,哎,进而。
09:30
哎,进而呢,哎会出现哎我们称为呢,叫ITW这样的一个事件。啊OK是吧,那因为呢,你出现这个STW了,所以呢,就会导致咱们整个这个用户的线程,包括咱们下边这个打印数据的这个线程,就会稍微的诶卡那么一下,那一卡的话呢,就大家就有可能能看到呢,咱们并不是每隔一秒钟呢,它这个停这个打印一下了。哎,能理解这意思是吧,诶通过这样一种方式呢,咱们让大家呢,去感受一下这个it tw啊这个事件的一个存在,好下边的话呢,咱们把当前这个线程呢,给人家打开,打开以后呢,我们跑一下当前这个程序。
10:09
行,那这时候大家能看到。你看。是吧,行,我这块就停掉了啊,那这呢是0.0,然后呢,下边的话呢,按说是不是该1.0啊,这2.0,这3.04.0 5.06.0是吧,当然你会发现呢,他们每两个之间的间隔呢,是不是超过一秒钟了。啊,这个呢,不是1.01.7啊,这个呢,也是一秒多一点,这也是多一点,这也多一点都多一点,那就是因为我们这个过程当中存在着这个STW这样的一个时间,所以导致呢,我们下边这个所谓的用户线程的执行过程当中,诶,他会有那么一点点卡,当然这块咱们感受不出来,只能是通过这个打印的数据呢,咱们去间接的做一个证明,对吧?OK,行,这呢就是咱们所谓的叫哎,Stop the word这样一个行为,诶关于这里边的几个点呢,大家需要关注一下。
我来说两句