00:00
接下来呢,咱们还是通过一个代码来给大家呢,做一个演示,演示一下说这个诶复活这样的一个场景啊,这块的话,我们把这个呢,就直接写好了,就看看re live是吧,这个呢,就是可以复活的这样的一个行为。啊,这呢是咱们来测试啊,这个叫object这个内容。嗯,Finalize哎,这个方法,当然这块我们测试的也不光是它了啊,咱们实际上呢,是进行重启了是吧?哎,测试它这个方法啊,或者呢,咱们理解成呢,就是测试一下这个对象的。啊。看气质。OK行,那么我们来看一下啊,当前我们这个类中呢,我声明了一个变量,这个变量我是个静态的。那是个静态变量,那咱们说呢,静态的这叫类变量啊,那这个类变量的话呢,是不是就属于哎,咱们说的这个叫j c roots的一部分,或者有直接呢,就属于GC root呗。那咱们前面不是已经说过了吗?说哪些结构可以作为g c root呢?其中有一个呢,就叫做类变量呗,包括占里边那个或者本地方法占里边那个局无变量表里边那些数据啊,常量池里边的数据是吧?哎,咱们都说过啊,行,然后接下来的话呢,这有一个叫泛滥的方法,我现在把这个方法呢,我先注释掉啊。
01:17
那这调的话呢,就意味着咱们没有去重写object类当中的这个trans这个方法。OK行注释掉了,然后在那方法当中,大家注意你看我这样写的先呢,把这个OB呢,我们诶负个值就扭了个当前类的对象,那逆完以后。1万以后这时候呢,相当于是我们是不是这些root,诶这样的一个引用呢,指向了你对空间中的一个对象,然后现在呢,我们把这个OB呢滞空。没了,那滞空以后呢,我这儿呢,显示的进行JC啊,此时呢,我们是不是会去调用垃圾回收器啊,哎,垃圾回收器对吧?哎,这时候呢,会调用垃圾回收器实现这个叫JC,那实验JC的时候呢,我们一看你当前堆空间中的这个对象呢,是不是没有任何引用指向你了啊,那就没有个引用链关系了,这呢就成为第一次标记呗。
02:06
第一次标记呢,它就是属于呃,待定的是吧,就可能要死了,它只能是从这俩里边呢去选所里边去选好,然后呢,这块我们程序呢,有一个叫sleep,那我这块为什么要执行sleep呢?主要是避免我们这个程序呢,过快的去执行它,那何必呢,主要是因为咱们这个finalize这个线程啊说了优先级比较低,咱们这呢,是不是主线程,哎,那么我们下边呢,去调用的时候呢,你让这个垃圾回收的时候呢,这个诶我们它执行的优先级比较低嘛,我们把这个主线呢,让它稍微的停一停,暂停了两秒,OK,然后呢,执行完以后。执完以后的话呢,我们这边判一下这个判断一下这个OB呢,是不是个闹,如果你要是闹的话呢,说明你死了,如果你要不是闹呢,说还活着。对吧,然后下边呢,我又进行第二次这个GC,呃,再让他复制这个账号,再进行一个GC啊调完垃圾回收器,下边这个代码是一样的。行OK说完了啊,那对于呢,我把这个已经注释掉的这样一种行为,其实注意啊,其实我这块代码没必要写了,因为呢,上边它就直接死了是吧,跑一下看看这个效果。
03:13
嗯,第一代呢,JC就是我上面不是有一个这样的操作吗?然后呢,咱们这个OBD呢,它就死了,那你第二它都死了嘛,他都死了,你第二次在JC它是不是还是死的。啊,相当于这个人这个这个都都已经挂掉了,你这咔咔就给人捅两刀是吧,他都死了啊啊就是下边这个按说是没有必要执行,诶这个呢,其实是对应的什么呀,就是当我们第一次标记的时候呢,哎,就是我们在这个位置。啊,然后你进行垃圾回收器回收的时候呢,我们JCE判断发现,诶你这个obj对应的这个对象呢,没有任何引用指向了第一次标记啊,它是属于这两里边去选,然后呢,由于咱们是不是说没有重写这个final的这个方法。没重启的话呢,直接就不可出击了,说明它就死了,所以死的话呢,你这块就dead,你下边再再再这次一次没用了,它都死了是吧,所以两次呢,都是叫is dead OK行,然后下边呢,你看我把这个finalize这个方法呢重写了或打开。
04:11
我把它打开,打开呢,这里边儿啊,这个呢,其实写不写无所谓啊,因为本身我们这个复类里边其实啥也没有对吧,关键呢,就是我下边这个操作。哎,关键是这个操作,那这个操作大家你注意一下,我们这呢,是不是说你是一个j c root要考虑的其中的一个引用啊,然后你,诶就让咱们当前这个对象就是调离方法,这个对象跟你这个OB呢,是不是要搭上关系啊。哎,这个操作的实现,实际上呢,就实现了这样一个说obj在发方法中与英链的任何一个对象建立了联系。是吧,哎,这个我们在这标识一下,当然这块呢,不是OB接了,是不是就当前对象呗。诶这样啊,说这个当前哎带。啊,回收的啊,对象在泛滥的方法中,与引用链上的任何一个对象呢,建立了引用啊,运引用链上的啊,我们就直接说一个对象啊,这个对象呢,就是我们叫OB接呗,哎,建立了引用,那你建立的引用呢,就是死不了了,就。
05:14
那这时候我们在吊它的时候呢,他又没死啊,这呢我们也看这个方法呢,什么时候掉啊,这块有这样操作对吧。这块我们要重点强调一下,说这个方法是不是只能被调用。诶一次,诶那它这个调用一次呢,那就应该是在咱们这儿呢,算是第一次标记了,然后真的我们要通过find来,呃,这个第一次标记完以后呢,接着通过这个线程呢,去这个执行的时候呢,诶要回收它的时候呢,我们这时候发现你重写了,诶这时候呢,我们是进行第二次的一个标记,对吧?哎就是说的这个这个环节呗。啊注意是吧,行,那这时候呢,我们去,呃在这个JC完以后呢,去执行的时候呢,呃发现呢,你这里边一个它调用了,再一个呢,你有一个引用了,那导致呢,我们这个对象呢,其实就没死没死成,那他没死成,我们再去等了,等他这时候你在判断的时候呢,实际上他是不是就不是闹了,哎,他就还活着。
06:11
然后你要再再次去调用这个GC的时候呢,因为我们上边这个方法只能调一次嘛,所以这时候呢,你就不会再去执行这个finalize了,那你又把它制成到了,又不会再调这个final了,所以它就是一个dead的状态。来跑一下,大家看看这个效果。你看第一次呢,这次的时候呢,我们就调这个犯人赖的方法了,哎,导致呢,他就没死成,因为呢,我们又把他呢,哎救活了啊说刀下留人是吧,这是我亲戚啊,这个有免死金牌,不能死好这块呢就没死成,第二次呢,说又要杀他了,说刀下留人,说这这闪开,这个只能执行一次啊,不好使啊,必须得死,所以这时候呢就带了。那就这样。嗯,行,这呢是给大家演示一下我们这个泛带这个方法里边,我们确实呢,是可以救活这个对象的啊,这是其一,其二的话呢,就是大家需要关注,就是这个方法呢,呃,涉及到我们这个对象呢,有三种状态在被回收的时候是吧?诶这个是一个面试题啊,大家记住它,那另外呢,就是关于这个翻带方法呢,大家注意,就是我们平时呢,重启的时候呢,一般干什么事?
07:14
啊,这个记住,然后呢,咱们一般呢,不会主动的去调,哎,通过这个垃圾回收器,它自动调用的一个finalize线程的去去直接执行就完了。啊,其实在咱们实际开发当中,一般咱们重启这个finalize方法的机会也比较少是吧?哎这样的啊,行,这个大家呢,整个清楚就行啊这呢是叫finalization的一个机制。
我来说两句