00:00
好,那关于这个方法区的讲解啊,咱们就进入到最后一个内容,涉及到叫方法区的一个垃圾回收的问题。那这是咱们最后一个内容,好咱们来看一下,说呢,有些人认为这个方法区啊,就比如说咱们houseor虚拟当中的这个叫员工间,或者说叫永久带了,嗯,说这个方法区呢,是没有垃圾收集行为的。啊,其实呢不然,也就是说呢,我们可以在方法区呢实现JC啊,那为什么他又说是是是可以回收,又又可以不回收,主要呢,是因为咱们Java虚拟机规范呢,对这块的约束呢,是比较宽松的啊提到过呢,说可以不要求虚拟机在方法区当中实现的一个垃圾收集。对吧,这个大家如果还有印象的话呢,应该这个能知道,咱们当初讲这个,呃,一开始讲这个方法区域的时候呢,咱们提到过这个规范,这个规范里边呢,你看是在在这块写的啊,说这个我们把方法区呢,看成是堆的一个逻辑的部分,这是规范里边说的啊,具体落地的话呢,我们说方法区呢,还有个概念叫飞堆是吧,说呢,一些简单的实现就是指具体的虚拟机了,比如说houseport呀,GI呀等等,他们呢都可以考虑选择呢,既不实现这个垃圾回收,那也不进行一个压缩处理。
01:11
啊,这个压缩处理呢,指的就是你要进行垃圾回收的时候呢,可能会产生一些内存碎片,这个内存碎片呢,需要进行一个整理,避免这个碎片化的问题,啊这个到我们后边讲GC的时候呢,说啊那这块就提到了,说我们是可以呃选择就是具体的扎va虚拟机就是落地的具体的产品是可以选择不进行JC的。如果真的要要不进行这些的话呢,那就真的是一个叫永久了。就是我们加载到这个方法区的中的中的这个结构呢,就是永远存在的。当然前提是我们当前这个查训的进程是不是不被销毁啊,你要是进程销毁了,那你整个咱们所谓的你这个运行时数据区是不是整个也就跟着销毁了,那你永久带当然也就没了,是吧,这个永久呢,指的是咱们这个当前这个进程存在的这个生命周期之内啊,还是永久存在的,嗯,那其实我们生活当中大家想是不是也没有什么东西是能永远存在的吧?
02:04
应该没有是吧,啊,就包括咱们说这个宇宙,它都有宇宙的一个诞生的时间,包括呢,宇宙呢,也有可能会有它消亡的一个时间,只不过这个时间呢,对于咱们地球上的生物来讲呢,可能这个时间太长了,看似呢像是一个永久的。包括呢,像咱们以前看到好多这个罗密欧朱丽叶呀,这个梁山伯祝英台啊,这个感人肺腑的这个爱情故事是吧,说这个情比金坚,那我觉得呢,是因为时间短啊,那你这个人的生命呢,可能就那么几十年,那你要是把这个时间呢,放的长一点,或者说当时这个这个年轻男女,这个刚谈恋爱的时候呢,这个这个激激素分泌是吧,荷尔蒙分分泌,然后呢,就是感觉这个这个要生要死的啊,哎,真的你要说这个。这个几十年的感情,或者呢,人呢可以活几百年,到时候我们看看这个感情呢,是不是还可以这个如此坚固,我觉得不好说是吧,哎,真的不好说啊,就世界上应该没有什么东西,我觉得是真正的是能叫永恒存在的。
03:03
啊,那嗯,古代的你像这个李白呢,是不是很早就看透这个事儿了,这个在枪剑酒里边写过,说莫使金樽空对月啊,千金散尽还复来啊,就是叫及时行乐啊,要不的话呢,好日子可能随时就结束了,到时候想享受也没有了,就这样个情况啊行,真的是古人这个诗人啊,写诗都比较潇洒啊,现在呢,咱们这个生活当中啊,都比较痛苦一些是吧?哎,被这个房贷啊车贷啊等等这个压着啊,压着呢啊行,所以有时候你想这个放松的话呢,也只能是一时半会儿的周末,哎,这个出去溜达溜达是吧?哎,正常上班的时候呢,可能还得996啊这样的现实啊。行,那咱们拉回来说呢,这个可以呢,不去实现这个垃圾收集,那这块提到了说事实上啊,咱也确实存在着未实现或者未能完整实现方法区,像类型卸载的这个收集器的存在,比如说后边我们讲这个垃圾回收器的时候呢,提到这个叫ZJC啊这个ZJC呢,它就不支持类的一个卸载。
04:00
那这个类卸载呢,主要就是针对于咱们这个方法去的这个垃圾收集行为嘛,对吧?哎,就这意思啊行,也就是说呢,确实存在这样的这个垃圾回收器啊,但是的话呢,对于咱们说的这个housewa虚拟机啊,呃,咱们还是有这个JC啊,还是有这个垃圾回收的。嗯,行,那下面来看一下说关于咱们这个方法区,它这个回收效果呀,还挺难让人满意的,尤其是这个类型的卸载啊,条件非常苛刻,一会儿咱们看一下条件非常苛刻,但是呢,这部分区域的回收啊,有时呢又特别的必要。大家有没有发现这其实是一个很矛盾的点是吧?啊,就是呢,呃,条件非常苛刻,然后回收效果不好,但是呢,又又有必要做这个呢,要是用咱们生活中的词儿,这典型的叫什么呀。费力不讨好是吧,费力不讨好就是干了这个事儿,结果呢,干了还不好啊,还被人埋怨啊,就成这样的情况了,像以前这个三公司,这个B格列宝当中就出现过若干的严重的bug,就是由于这个低版本的house虚拟呢,没有对这个区域进行完全的回收,导致的这个内存泄露。
05:01
啊,出现这个问题,所以说呢,不回收还不行,但回收吧,这个效果还不是特别好,哎,很尴尬啊,那么我们要是谈这个垃圾回收的话呢,针对方法区应该怎么进行回收呢?这里边提到了主要呢回收的是两个东西,那其实也是针对于你这个方法区主要存放的信息,那方法器呢,主要存放呢,我们说就是叫类型信息啊,另外呢,叫运行时常量池。对吧,那前面呢,咱们不是讲了一个算是一个经典的结构,嗯,经典的结构找一下。那经典结构呢,我们是在这讲的,然后后边的话呢,讲这个静态变量有变化,运行式常量池里边这个自符差产量池有变化,那预信息呢,方法信息呢,一定程度上我们也都可以统归程是关于这个类相关的一些类型信息,那也就是说在这个图当中,其实描述的话呢,是主要的我们方法区的这个结构,一个呢叫类型信息,一个呢叫运行式常量池,那么我们进行垃圾这个回收的时候呢,其实针对的也主要就是这两这两个区域呗。对吧,啊很好理解,行,那我们就一个一个来看啊,首先的话呢,提到说你这个叫废旧的,这个废弃的一些常量。
06:06
那所谓的常量呢,主要指的就是这个叫自变量和这个叫符号引用。啊,说自变量叭,较接近于Java语言这个层次,这个叫常量的概念,比如文本字符串啊,生命中final动的这个常量值啊等等,那符号引用的话呢,属于边原理方面的这个概念,哎,这个什么是符号引用,咱们也都说过了啊,那主要的话呢,涉及到了像类核接口的权限的名字段啊,方法的这个名称和描述等等,哎,这呢都看能是这个常量,那关于这个常量的回收呢,其实比较简单,就是你不用了我就回收。啊,只要你不用就回收啊,没有任何引用,引用到了这个地方啊,具体的这个回收的策略方法,这个咱们,诶后边这个章节呢,给大家去讲,这个叫JC了是吧?啊你就知道呢,只要不用了,我们就认为是垃圾就可以被回收了,跟咱们回收这个堆中的对象啊非常类似,所以关于常量的回收呢,比较简单,这个费力不讨好呢,主要针对的是我们说这个类,说要想判断一个类不再被使用了,这个条件呢,就非常的苛刻,需要同时满足如下的三个条件。
07:04
这是一个且的关系,就是三个都得满足。啊,大家想想,我们说这个类呢,不要了,就是完全不用了是吧?哎,我们才有可能把这个类呢,进行一个清理清除,那这个类不用意味着什么呀,说你这个类啊,所有的石类呢,都已经被回收了。啊,因为只要是堆空间中有你当前这个类的实例,那你这个呃实例的话呢,它就一定会有一个呃指针指向了你方法区中的你这个类型信息。啊,所以你这个这个要想不用的前提呢,是你这个指针不存在,也就是说你当前这个类的所有实例呢,都不能在,不光你这个类的实例不能在你这个类的任何此类的这个对象呢,是不是也不能存在呀。因为我们说有继承关系存在的话呢,子类对象也是可以来调用你这个所谓的负类中的结构的,对吧?OK,这个呢,本身实际上呢,就有一些苛刻,你像我们这个进行这个判断的话呢,也需要花一定的时间,对吧,这是一个啊,另外一个呢,说加载该类的类的加载器呢,已经被回收。
08:01
加载该类的类的加载器已经被回收,诶这个怎么去理解这个事儿呢。啊,这个大家呢,再看一下咱们前面讲的这个图,嗯,看下这个图,咱们简单的做一个描述。啊,这个咱们之前呢,带着大家看这个自解码文件,自解码文件里边呢,实际上是没有记录类的加载器的,你去搜索咱们也搜过是吧,这个但是大家也搜过啊,搜不着,但是呢,你这个资金码文件呢,咱们使用类的加载器加载到内存中以后呢,诶,它不就放在我们这个所谓的叫方法区了吗。放在这个区域里边是吧,那这个方法区里边啊,咱们关于当前这个类啊,比如你这个是类叫类A,那那我这呢,就放在内存当中,诶把这个类A就给加载过来了,这个类A当中是记录了它是由谁进行加载的,也就是它所谓的类的加载器是谁是记录的,那同时这个类的加载器呢,它也记录了它都加载过谁。是吧,它都加载过谁,那现在呢,就是说呃,你这个类的加载器,你想想这个类的加载器要是呃要被卸载的话呢,那你这个类A呢,是不是相应的也就可以被卸载了。
09:04
那因为这里边要用这个类的加载器,它呢都已经被干掉了,你也会跟着被干掉是吧?哎,就是你当前这个类的加载器呢,如果被卸载了,那也要诶被干掉当前这个类。但是通常的话呢,我们都很难达成。啊,一般呢,我们说这个类置驾驶器呢,呃,被回收了,这个可能性都不大是吧?呃,这个呢是很难被达成的,那再一个呢,就是说我们这个运营实类本身呢,是不是还要对应一个大的class的个实例啊,这个大的class的这个对象的话呢,他也没有在任何地方被引用过啊,咱们使用反射的时候呢,要用到大的class这个实例,它呢没有被引用过啊,没引用过的话呢,诶我们才可能考虑说当前这个类呢,确实是不想用了。哎,得满足这样的几个条件,哎都满足以后呢,我们说才允许是吧,只能说允许可能被回收,当然也不是说呢,一定就能够被回收。它还跟对象不一样啊,对象来说没有引用就会说它还不是,那关于这个类型是不是回收,我们还有相关的一些参数控制,这呢就不多说了啊,那总之一句话呢,就是我们关于这个类的卸载啊,实际上是很苛刻的,而且呢,实际上实施的效果呀,可能并不好。
10:09
啊,并不好啊,那在我们说大量的使用反射动态代理,我们去加载这个类的时候啊,CD lab这个自建码框架的时候呢,我们如果说加载的这个类呢,诶过多这个时候呢,咱们还确实需要呢,具备这种垃圾收集的能力。啊,避免呢,对我们的个内存呢,造成过大压力啊,这呢就是我们说具体的一些场景下呢,咱们在具体的考虑这个GC,哎,放下去的GC啊,那大家呢,只需要记住我们关于方法区垃圾回收的这样几个事儿啊,总结一下第一个的话呢,就是方化区要不要垃圾回收,这下区你规范当中没有明说,就是你可以回收也可以不回收。啊是这样,而且呢,咱们也确实存在着这个对相应的一些这个类呢,卸载不支持的一些垃圾回收器,那它的性能呢,其实也就会更高一些是吧,那如果说你要是回收垃圾的话呢,我们说主要回收的是什么,这个你得知道。
11:01
啊,那事实上的话呢,这个常量的话呢,还好这个类型这块呢,就是费力不讨来记住这个事儿啊就可以了。
我来说两句