00:00
诶这儿呢,就是咱们刚才给大家介绍的这个环节123,还有呢,有可能的这个环节四对吧,那这个环节呢,概述说完以后呢,按说咱们开始具体的介绍这些细节了,当然这些介绍这些细节之前呢,咱们先有一个储备的一个知识,这个知识呢,我们叫做remember的set,简称呢,叫做rset啊你把这个一删就是ret这个意思,呃,什么叫做呢?记忆集呢,翻译过来叫做记忆集对吧?呃,其实呢,我们在前面呢,讲某一个知识点的时候呢,我提到过这个记忆,记忆集级,不知道大家呢,还有没有印象。就是我们在讲到这个这first的时候呢,说它的这个缺点的时候,说相较于我们这个CMS,包括呢,其他的这个垃圾回收器说呢,从经验上来讲,这个这first垃圾回收器,它还需要额外的占用10%是到20%的我们这个内存空间啊,那那个内存空间主要用来干什么呢?这里边就提到了其中的一部分内容,就是叫做remember the set。就是用来存放我们这个记忆集的,那为什么我们需要使用这个记忆集呢?我下边呢,看写了这样的一些文字,那这个文字呢,虽然看着挺多的,但其实上呢,给大家一讲呢,哎,你就能够理解是什么意思了。
01:08
诶就能理解是什么意思了,咱们主要目的呢,肯定是为了更好的,是不是回收这些垃圾的是吧,毫无疑问啊,在这里边我们涉及到一个点啊,什么点呢,你看一个对象呀,咱有可能是不是被不同区域的这个引用所引用啊。被不同区域引这个对象所引用,比如说我这块看这吧,这呢有一个叫伊甸园区,这里边呢,有个对象呢,被这个伊甸园区的引用了,引用了,然后也有可能被这个一区的这个对象所引用了,那这时候呢,其实还好,什么意思啊,咱们要进行垃圾回收的时候呢,你这个样JC,那就咱们这都是样JC的一部分嘛,都是伊甸园区,所以咱就都回收,但现在的问题就是说,我们是不是也有可能有这个O的区,就是养老区的这个引用呢,是不是指向你这个对象了,那这个时候的话呢,是一种场景,那你想想我们要想回收某个对象,咱们要判断说你是不是可达的,这个咱们前面都说过了,你想想这时候我们要是在进行这个样JC的时候呢,咱们除了把这个伊甸园区和这个呃,Survivor区呢,遍利完之后,说你还得把所有的这个old区也变了一遍,看一下你这里边这个对象呢,有没有被引用,这个事儿大家想想是不是就比较崩溃了呀。
02:16
为啥呢?因为呢,我们现在明明在样JC对吧,我们明明在样JC,但是呢,咱们还需要把这个老年代的这些区域呢,这个都还得便利一遍找一下,看看是不是引用了我们这里边这个,呃,这个伊电园区的这个数据,这个效率呢就非常的差,你像我们在变历的时候呢,咱们说它得是一个STW的,你这时候呢,你这个延迟它一定短不了。那那这时候呢,我们就设计了一个东西,这个东西呢,就称为呢叫remember的set,就叫做记忆集来,那我们先来看一下这里边这文字上的一些描述,说一个region呢,它不可能是孤立的一个region的对象,有可能被其他任意的region呢所引用,这个任意呢,就涉及到你可能是新生代的,这个被老年代的所引用了,对吧,他是可能跨这种带的啊。
03:02
那判断对象是否存活的话呢,咱们就需要呢,去扫描这个堆,但是你要不要扫描整个堆呢。那你要扫描整个堆,显然的问题呢,就是说STW的这个时间呢,比较长,这个在其他的这个分带收益器中也存在这样的问题,那只不过呢,我们说j first呢更突出,因为咱们说这个j first呢,首先它有很多的region嘛,对吧,它有很多region,这是其一,其次的话呢,它主要针对的还是这个大大对是吧,就我们堆越大的话呢,这个G是不是效果就越好一些啊,那你堆越大的话,你扫描起来是不是花的时间就越长一些啊,很显然的问题,对吧?那么回收新生代也不得不同时扫描老年代,就是我刚才说的这个问题。有可能你这个老年代呢,是不是引用了我们新生代中的对象呀,所以这个呢,又跟咱们以前那一个知识点联系起来了,不知道大家还有没有印象,就是咱们以前呢讲这个说哪些对象可以作为叫jc roots的root呢,说过这个虚拟站中的这个局部变量表啊,本地方法站的这个这个变量对吧,还有这个静态的这个,呃,静态域,还有这个常量池啊等等,包括这个同步的那个锁啊,咱们都说过,然后紧接着呢,我第二张PPT的时候呢,又提到过,说呢,如果你只想回收某一个区域的这个数据的话呢,我们非这个区域的这些。
04:17
哎,这些这个这个引用是不是也有可能作为这个GC roots的一部分来考虑啊。比如说你看我们现在谈的,你现在要回收这个叫伊甸园区的这些region的时候呢,我们有可能是不是就要考虑O的这个老年代里边的一些引用,是不是要使用你了。那这就我们说的这个区域化的一个回收的时候呢,这个GC root呢,有可能这个概念呢会被放大,那这个呢,如果大家面试的时候,你把这个点也提出来,这个还是非常具有亮点的,因为呢,你去网上搜的话呢,可能搜出来都是这些这个内容的话呢,不一定都会去提到,对吧?哎,这就说明你看问题呢,还是比较全面的啊行,那么我们再拉回来提这个点。说你要是回收这个伊甸园区,把所有的O区都变了一遍,哇,那简直是很崩溃,咱们也提到过这个问题,肯定呢,会降低咱们的mini DC的一个效率。
05:05
不行是吧,不能这样玩,那怎么玩啊,所以我们说这个都使用这个概念来避免呢,进行全局的一个扫描,怎么就能避免了呢?先来看个图,先来看这个图上边呢,就是我们说的这叫region还是region对吧?我们呢,给每一个region啊,咱们都给它配一个叫做remember的set,就叫做记忆级,给每个region都配一个,那比如说呢,我们针对于中间这个REGION2啊,针对于他来讲这个region的话呢,咱们用这个记忆集呢,来记录说哪些这个引用呢,指向了你这个region区域中的这个对象。比如我们这里边两个率的对象是不是被我们这个,呃,REGION1当中的这个引用呢,指向了一下,被REGIONGEN3中的这个引用呢,指向了一下,我们在这个记忆集当中就记录一下你这个REGION1和REGION3中的这两个引用。诶记住这引用,那么回头呢,如果我们想去回收这个区域了,想去回收这区域了,大家呢,是不是用不着去进行全堆这个便利了,咱们直接是不是看一下你这个记忆集就可以了,对吧?诶看记忆就行,就比如说你这是一个女生啊,这个女生的话呢,说看看哪些男生喜欢我呀,这块呢,我就先整个小本本先记一下是吧,看看谁喜欢我,谁喜欢谁,哎从这里边我挑一个挑一个合适的是吧?哎,你要不记录的话呢,这个你也不清楚,那这块呢,一个一个问是吧,谁谁喜欢我,谁喜欢我,谁喜欢我,这有点恶心了就是吧。
06:29
啊,这个例子呢,有点奇葩是吧?行,知道这个意思啊,然后回过来看一下我们这里边这个文字上的一些描述,说呢,每个region呢,咱们都有一个记一集,说每次呢,这个引用类型写操作的时候呢,我们都会产生一个叫写屏照,哎,这呢有一个新的词叫写屏障,使用这个写屏障呢,我们暂时的去终止这个操作,然后呢,去检查一下,说你要写入的这个引用所指向这个对象是不是和我们该引用的类型呢,是分配在不同的这个region当中的。就我们这块呢,先给他拦下来,说你看是不是不同的region啊,如果你要是同一个region的话呢,大家你想自己引用自己,反正呢,你回头要回收,是不是也要扫描一下我们自己这个region就可以不记录了,是吧,那你要是来自于不同的region的话呢,咱们就要记录一下。
07:14
那所以这块如果要是不一样的话,不是同一个region,咱们这时候呢,就通过这个叫卡表叫car table啊,通过这个卡表呢,把相关的这个引用信息啊,就记录到引用指向对象的所在region对应的remember set当中,这句话呢比较绕,其实就是我们说的这样一个场景,把这个呢就记录到这儿,这叫卡表是吧,就记到这儿了。行,嗯,那么接下来双当进行这个垃圾回收的时候呢,在JC这个根节点的枚举范围内呢,我们加入这个叫remember set,就是我刚才说的加入这个所谓的这个局部的,呃,你要局部进行回收的时候呢,我们,呃,在你这个JC这个入之外呢,我们加入这个局部的一些考虑的这个引用是吧?诶加入这个remember set这样的一个集合,保证呢,不需要进行全板的一个扫描,不会有这个,而且呢,还不会有遗漏,遗漏,那这样呢,就能够避免我们这个JC的效率呢过低。
08:05
能理解这个事吧,行,这呢就是我们说的这个叫remember the set,包括呢,还有一个概念呢,叫做写屏障啊写屏障这样一个词,OK,行,那这个呢,Remember side呢,咱们就先说清楚,那接下来的话呢,咱们就开始说明一下具体的这样的几个过程啊。
我来说两句