00:00
那讲完了说引用技术算法之后啊,咱们来看一下这个叫可达性分析算法啊,这个呢,是我们说标记阶段的这个算法呢之二啊这个呢,也是咱们Java呢所选择的一个算法,那这个可达性分析算法呢,它还有其他的一些名字,那也可以称为呢,叫做根搜索算法,或者呢叫追踪性垃圾收集,这个大家在不同的书上或者帖子上呢,你看到的时候呢,不要惊讶,说呢跟搜索方法跟那个可达性分析算法什么关系呢?实际上呢一样的,这呢是通过不同的角度呢,来进行的一个说明啊,进行的一个命名行,那下边说相较于这个引用技术算法而言,可达性分析算法啊,不仅同样的具备实验简单和执行高效的特点,那更重要的是呢,它能够解决咱们在讲这个引用技术算法中提到的,这叫循环引用的问题。对吧,这个循环引用呢,我们说是引用技术算法里边一个致命的缺点,那其实它这个好处的话呢,就是执行比较高效是吧,然后呢,你也可以没有延迟性的随时呢进行垃圾收集啊,这个是非趁好的点啊,当然呢,循环引用了非常致命啊,虽然说这里边提到说这个可达性分析算法啊,说同样具备,说实现简单,执行高效,但是相较于咱们说的这个应用技术算法来讲,呃多少呢,这个可弹性分析呢,还是稍微要复杂一点。
01:12
还是要稍微复杂一点,但是呢,这个功能上还是比较强大的,OK,那相较于这个引用技术算法说,咱们现在讲的这个可达性分析算法呢,就是Java语言,包括呢,像c sharp语言呢,所选择的啊,进行垃圾标记的时候呢,就是使用的这个可达性分析算法。啊,那也可以称为呢,叫追踪性垃圾收集啊,纯性该被collection。啊,这个呢,就是都OK是吧,就是这个呢,大家知道这几个名字是一样子的,那首先呢,我们先明确一下这个可大性分析呢,它的一个实现思路是什么样子的,啊这呢我就写的比较清楚了,说可大性分析算法呢,是以根对象集合作为呢起始点,那什么叫根对象呢?那这呢,我提到了根对象就是一组必须活跃的引用,那因为有很多,那就是它构成了一个集合,叫JC入此,这个S呢就是表示复数的意思,对吧?那按照从上至下的这个方式去搜索被跟对象集合所连接的目标对象是否是可达的。
02:11
啊,因为涉及到跟对象了,所以我们称为呢叫根搜索算法,是否可达呢?所以叫可达性分析算法,对吧?行,那咱们这块就看这个图,比如说呢,我们现在已经有一波这个数,呃,一波这个元素引用,咱们可以把它那认为觉得roots了,就是因为它是一个活跃的一会儿咱们看具体有哪些,对吧?行,那么由这个roots出发,它是个根儿,就像咱们前面讲这个,呃,这个类的一个竞能关系一样,啊最上边这个object就是个根,然后往下呢,看看它呢,分别引用了哪些对象实体,就是对空间中的这个结构,那它引用了这个object 1object有引用二,二有用四,啊一还引用了三,那么像这里边的1234,他们呢,诶就都不应该被进行垃圾收集。诶都不应该被垃圾收集,就看见是不可达,像这里边这567呢,显然呢,从我们这个roots开始呢,就不可达,就是你通过这儿呢,是没办法走到这儿的,诶这个大家注意行,那么经过这个可达性分析算法以后呢,说这个内存中存活这个对象,直接或间存活对象呢,就是指能直接或间接的被连接到的,我们就称为呢,它应该是呃要存活的,那么这里边这个引用关系呢,我们就称为呢,诶叫做一个引用链。
03:18
啊,Reference chain是吧,诶这样的一个引用链,OK,那么如果没有被这个引用链所引用到的这个场景呢,像这里边567他们三个啊,就应该要被回收掉,说白了就应该是这个垃圾对吧,这意思不可达的就应该是垃圾。OK,那只要是存活的对象呢,咱们都应该直接或间接的被咱们这个roots所连接上。诶注意你看我这边说的这个语言,只要呢,你是存活的对象呢,都应该直接或间接的被这个GC root呢所连接到,而这个呢,没连接到呢,就是打击行行对吧?这呢我说比较好理解,那这个呢,我再举了两个例子,一个呢,就是咱们生活当中,大家呢,如果去买葡萄的时候,买葡萄时候呢,一般咱们都是抓上面这样一个杆儿,对吧?那一抓起来的时候呢,那下边呢,凡是直接或间接的跟你这个杆相连的呢,那肯定都被拽起来了。
04:10
那有的时候呢,你买葡萄的时候,下边是不是也有很多散落的那些葡萄,那散落的那些呢,咱们就可以认为是垃圾了,因为呢,没有直接或间接的是不是被这个我们这个杆儿呢,杆儿呢所连接,对吧,这是一个。那另外一个呢,就是呃,这呢是咱们看那个人民的名义里边啊,呃涉及到这个在官场上,包括呢,像古代这个封建授一样是吧,就是这个,呃,官场上的这种裙带关系。嗯,直接或间接的去连接的,那你要是你是一个,嗯,你说你能力特别强,但是呢,没有任何的这个关系网,那你这块呢,就是属于被排除在外的啊,这个混起来呢,就比较困难一些是吧,这是我们所说,就官场当中这个叫裙带关系,OK。那咱们古代的话呢,实际上呢,也有一个词叫什么呀,叫做这个啊,一人得道,鸡犬升天对吧?啊那其实呢,描述的你想想是不是就是对我们这个可达性分析,在社会上是吧,在人的这个关系上的一种描述。
05:04
鸡犬升天并不是说真的是鸡科之犬,那你可以用来形容的就是那些能力比较低的一些亲戚朋友是吧,本身没有能力,但是呢,也跟着都升天了。啊,这种裙带关系。那说的呢,就比较形象一点,OK,那这个可达性分析算法呢,应该算是比较好理解的一个点,对吧?行,那下边呢,咱们再看另外一个概念。那另外一个概念说到你这里边提到这个jc roots了,那到底我们障碍员哪些结构可以作为这个GC root呢?那这呢罗列出来了,那面试的时候呢,注意这个问题呢,是可能会被问到的,而且呢算是一个比较高频的问题,说呢在Java语言中J些可以是哪些具体的元素呢?OK,你看我这里边写的比较清楚,诶这个Java虚机占中引用的对象,这呢也是我们说最为常见的。啊,占中引用对象那主要呢,就是放在这个居无变量表里的,局无变量表里边放在那些引用啊,诶我们说只要你是引用啊,是是引用,不是那个基本数据型的内容,对吧,你引用的指向了对空间的那个对象实体的,那你这些引用都一定是GC入S的这个集合中的这个结构。
06:05
啊,这个大家注意啊,各个线程被调化方法中的参数局变量对吧?诶放在局无变量表里的那些引用啊,另外一个呢,就是本地方法站,那涉及到虚拟站,在本地方法站呢,同样的来考虑,就是native的这个方法赢的这个对象。行,然后下一个呢,就是这个方法区当中这个类的静态属性。那静态的这个引用变量,那因为涉及到静态了,它就没有放在我们这个具体的这个虚拟站里边了,那你在其他的一个结构里边,因为你是静态的啊,我们说原来的时候呢,考虑是在方法区,后来呢,JDK7这个七以后,咱们是放在这个方法这个放在这个对空间对吧,当然你主要关注就是这个静态的结构啊,它呢,也是作为我们说的这个,呃,这些入此的一部分,还有呢,就是这个常量池的引用啊,比如说子差常量池里边的引用,它呢也是为我们这个这些如此它的一部分,还有呢,所有被同步所S持有的对象,就我们说那个同步监视器。对吧,那同步监视器肯定不能够被销毁,销毁以后呢,我们这个同步就失效了,对吧,所以它呢,也作为咱们这个GC root的一部分,那以及下边还有其他的一些结构啊,比如说基本数据类型对应的这个class对象。
07:08
啊拉对象,常驻内存中的这个异常对象啊,以及呢类的加载器啊,这主要指的就是系统类加载器啊,这要注意,那还有呢,其他的这样一些相关结构啊,本地代码缓存等等啊,这个呢,我们见到的情况就稍微少一些,主要大家啊面试的时候如果让你去打的话呢,诶这几个一定要说出来,当然这个同步的话呢,还有我们这个系统类加载器啊,常驻的异常对象啊,Class对象啊,这个能说出来那更好了。OK,这呢,就是我们说的叫gcs。斜向点来说呢,大家会发现,如果这儿呢,我们看成是一个堆空间的话,就我这个这个什么青色的这个部分是吧,堆空间的话,你非堆空间的,像这些你占空间啊,方法区里边的呀,常量池里边的呀,是吧,这样的一些机构,你如果都引用了这个堆空间这个对象实体的话呢,那这些呢,像我这里边儿这个蓝色的,它都属于这个叫可达的对象。啊,那你这些所谓这个红色的这些结构呢,因为呢不可达了。
08:03
所以呢,就是垃圾,因为呢,没有直接或间接的被我们这个这些入呢,这个引用呢,所指向是吧,哎,他们就都是垃圾了,就这里边这个红色的。OK,行,那我们回过来啊,那通过刚才这样一个描述呢,我希望大家能够记住的一个点,就是一个技巧。就是我这里边写了一个技巧,就是这些root到底哪些结构可以作为jc root呢?大家可以这样来看,说呢,在这个root当中,它采用这个站的方式来存储变量和指针,那如果是呃,这个如果一个指针它保存了这个堆内存当中,里边这个对象的话呢,但它自己又不存放堆内存里,又不存放在这个堆内存里边,它就是个root。或者换句话说呢,就是呃,咱们所有的是这个堆空间的这个周边是吧。啊叭如站啊,虚拟站,本地方法站,方法区啊,长景池等等,就是你周边的这些结构里边有的那个引用呢,其实我们都可以考虑呢,哎,作为这个叫哎jc roots,或者叫J些root是吧?哎结合在一起就是个root了。
09:01
就是形象点,大家呢,就这样去做一个小技巧来进行一个记忆啊行,那上面这块呢,我又提了一个特殊情况,那如果面试当中大家能把这个点答出来,那就是高端的。就是高端的,就是除了咱们刚才提到的这些之外,对吧,我们说呢,还有可能会把一些其他的对象临时性呢,也加入到我们这个GC root当中,比如说分带收集和局部回收。诶什么意思啊,哎,其实就这个意思,比如说咱们现在考虑的刚才说的都是对这个堆进行垃圾回收,那现在的话,如果说这个堆啊要进行垃圾回收呢,说这个堆的这个周边呢,咱们都可以看成叫这些root了,那现在如果我们只考虑这个新生代的这个回收的话,就只考虑这个局部这个结构,那此时的话呢,非新生代的,比如说这个其他的这个老年代等等,是不是就应该考虑也作为这个GC root的一部分,对吧?因为你单独的看了个新生代的话呢,我们有可能被这个老年代中的一些引用所指向了。
10:00
那类似于这样的场景,所以说我们还要考虑到这个非刚才说的这个部分,那还可能要考虑到这个局部的这个问题。啊,这呢,就我们说的这叫居无回收,哎,我在下边儿呢也写了。OK,行是吧,好,那这呢,就咱们整个要谈的,这叫可达性分析这个算法啊,这呢我写了个注意说如果要使用可达性分析算法判断这个内存是否可回收收和可以回收呢,那么分析工作必须在一个能够保证一致性的这个快照当中进行。啊,这点不满足的话呢,分析结果的准确性就无从保证,这个一致性大家应该能理解吧,咱们学Java的话呢,是不是包括数据库事物啊等等acid属性啊,是不是经常会提到这个一致性的问题,对吧,你得保证我们这个数据呢,它是一个准确正确的。啊,这个点呢,是必须要保证,就是在咱们整个呢,进行这个分析期间,整个这个执行系统看起来呢,它就像被冻结在某个时间点上。啊,不可以呢,出现在分析的这个过程当中,我们这个对象的引用关系呢,还不断的变化,那就坏事了。
11:00
能理解吧,哎,就像引用关系还不断的变,那我们现在刚标记完,回头呢又不用了,或者刚说不用了,回头又被标记上了,当然这个可能性不大,因为已经没办法引用它了,就没办法再标记是吧?哎,现在刚标记上,呃,你说呃那个表示它是可达的,然后呢,下一刻你把它这个指针又去掉了,这个呢,它就没有这个一致性呢,一致性呢就会不能保证了,那就出问题了。哎,这个大家一定要注意行,那么正因为呢,我们这块有这个一致性的要求,所以呢,咱们要求在判断这个,诶这个叫什么。哪些对象呢,应该被标记的时候呢,我们必须要求啊叫SCW啊,就stop word将用户限制呢,给它停下来。啊,给大家停下来啊,下边说的即使呢,号称不会发生停顿的这个CMS是咱们后边要讲的这个垃圾回收器,它呢,诶其实在判断就是确定被这个根节点呢,所引用的时候呢,也是一个需要被停顿的。啊,没有绝对的说不让停顿在这样垃圾收集器。啊这个要注意就CMS呢,也是咱们说第一个它是叫低延迟的一个垃圾收集器啊,是一个叫并发执行的这样的垃圾收集器,但后边呢会讲OK行,那这呢,我们关于这个可达性分析呢,咱们就诶说清楚了,大家重点需要掌握的就是诶它为什么是Java的一个选择能解决的问题呢?诶这呢,是不是就把这个循环引用的问题这块我们就干掉了,对吧?那按照引用技术算法呢,这几个呢不是垃圾,但实际上呢,他们是垃圾,OK,这是一个。
12:23
那另外的话呢,就是说大家需要记住的就是到底哪些元素呢,可以作为这个GC root啊,要记住它以及呢,另外高端的一个这样。那还可以有一些临时性的对象呢,被加入啊,为什么如何理解啊,就是这样一个意思,OK,行,那这儿呢,我们就说到这儿。
我来说两句