粉丝4149获赞2.3万

好的,今天呢,我们就一起来聊一聊垃圾回收器之一。那关于之一,我们将分成两期视频,本期视频呢,主要对之一进行概述,从三个点来讲,什么是之一?之一?他是如何分区的?之一和 cms 的差别是什么?话不多说,点关注我们开始。首先什么是之一? 之一呢?就是 garbage first, 意思就是首先回收垃圾对象特别多的地方,那之一是继 cms 之后,新一代面向服务器的垃圾回收器,他不再严格的按照之前的老年代和新生代的划分来进行垃圾回收, 因为我们这些垃圾回收器都是单独服务于老年代或新生代的嘛,它是一个老年代和新生代可以共用的一个垃圾回收器,主要针对配备多核 cpu, 是大容量内存的机器。那为了是满足可控的 gc 停顿时间, 那可控的 jc 停顿时间就是我可以人为的设置,我垃圾回收会阻塞用户线程多久,那同时呢,还具备高吞吐量的这么一个性能 特质好。第二个点之一是如何分区的?那我们以前讲的这个 g c 回收器啊,它是对整个新生代或者说是老年代进行垃圾回收的,要扫描对象很多, s、 d w 的时间呢就会较长,但之一就不是。之一,采用的是局部收集的设计思想,它是以 region 就这么一小格一小格为基本单位的内存布局方式来进行的, 将那个假马堆空间呢划分成多个大小相等,注意是大小相等的独立区域,就是我们说的 region, 总共不超过二零四八个 region。 那这个是由 g v m 的原码参数去控制的,我们可以看一下他分了哪些区域呢?就一等区, survivor 区, old 区以及 humorous 区,就巨大的, 那通常这个锐震大小呢?等于对空间总大小去除以这个锐震个数,那就比如说对空间是四零九六 nb, 那总共分了二零四八个锐震,那每个的话除一下就是两兆吗?我们一般推荐默认的这个计算方式啊,那具体这里面每个区放什么东西,我们 会在下期视频中进行讲解。好,第三个问题,注意和 cms 差别是什么?那主要有这几个维度差别。适用范围, sdw 的时间,内存碎片以及回收过程。首先是适用范围, cms, 它是一个老年代专用的这个垃圾回收器,那之一的话是全部都适用的。然后 s t w 时间的话, cms 是以最早停顿时间为目标,是不可设置的,那之一是可以设置我预期的停顿时间的,通过这个参数来设置啊,那内存碎片 cms, 由于它那个垃圾回收算法是标记清除,所以说会存在内存碎片的问题, 这我们在上期视频中进行过一个详解,那之一的话,它是标记整理降低内存碎片这个问题,同时呢它是分块的内存空间,就我们刚刚上面说的那个一个 region, 这个设计思想呢,避免了内存碎片的存在。好,最后一点呢是回收过程, 回收过程差别是什么呢?我们来看张图, c m s 这个收据器啊,它是初始标记并发标记,重新标记并发清除。那之一的这个垃圾 回收器呢,他是初始标记并发标记最终标记,然后是筛选回收,最主要还是这个筛选回收啊,那这个筛选回收到底是怎么样的呢?啊?这块东西内容比较多,我们会放在下期视频中进行给讲解。好的,本期视频呢,我们主要从三个点来讲一下这个之一回收器到底是怎么样的东西。欢迎大家点赞关注,收藏留言,后续不迷路,让我们一起进步。

那接下来的话咱们看一下这个 j first 垃圾回收器呢,具体在回收垃圾过程当中的一些细节问题啊,这块呢大家也会看到,就比我们前面讲的具体的某一个垃圾回收器呢,要复杂一些。 哎,主要原因呢是因为咱们前面讲的这个垃圾回收器啊,他们要么呢是针对于这个叫新生代,要么呢是针对于老年代呢进行垃圾回收的。 那新生代的话呢,我们提的呢就是比较频繁一些对吧,哎,频繁的去收集这个新生代里边呢设计到叫这个一定元区 c y 二零区 c y 二一区。具体这个细节呢,不同的垃圾回收性呢,会不太一样, 主要呢就分成这叫串型和并行的这样的一个区别。那么针对于老年代这块的话呢,我们说哎,这个频率比较低。那这块我们提到的叫 cms 这个垃圾回收器,还有 siri o 的,还有帕罗拉 o 的这样的三款呢。主要的老年代的垃圾回收器细节呢也有些不一样。那相对来说呢,这个 cms 呢,算是比 比较复杂的,我们讲了它有具体的四个环节对吧,这个处置标记啊,冰花标记啊,这个清理啊等等,冰花清理啊,重新标记啊等等这样的环节。 ok? 那么 我们现在呢来讲一下这个叫 j first 垃圾回收器。这个 j first 垃圾回收器呢,首先明确呢,他不光针对于说新生代或者老年代了,这两个区域呢,他都可以回收,这呢是基于我们说叫瑞震,也就说呢叫分区算法对吧? 那这呢我们会看到这个内存空间呢,就是这样的一个一个的小方块,每个呢都是一个 ray 震,那它用于存储着不同的这个结构, 所以这块我们在回收的时候呢,结构就会显得呢稍微的复杂一些。那我们来看一下具体这个环节。那么针对于这个这份垃圾回收的话呢,我们说主要包含的,主要包含的啊叫三个环节,也就是说必须要包含的是三个环节,那还有可能会出现第四个环节,所以这块呢我列出来了,但是加了一个小括号, 加了个小括号,那一定会出现的话呢。首先提到了叫做年轻贷的 jc, 也是我们所谓的叫央 jc, 或者叫做 mina jc 都可以。然后再进行这个老年代回收的时候呢,我们首先需要进行老年代的一个叫并发标记的一个过程, 老年代一个并发标记的过程,那就是肯看完他一个 marking 并发标记,然后这个并发标记结束完以后呢,我们要进行一个混合回收,叫做 mix 的 jc。 这个 mix 的 jc 怎么叫混合呢?因为他涉及到了年轻代和老年代共同的一个回收过程, 那就是我们指的这个环节。 ok, 那么这块呢,你看我还列出来一个点说,如果需要的话呢,这个单线程的独占式的,高强度的一个 fog c 还有可能会存在, 那他呢也相当于咱们前边类似。于是不是讲这个 cms 的时候呢,我们说当你这个 cms 呢出现这叫菲力失败机制的时候呢,我们也会使用叫希尔 cro 的,是不是作为一个后背的一个方案对吧?那这呢也类似也类似,就是我们这个 j 一垃圾回收器或叫 j first, 他在回收的时候呢,是有可能会触发我们的 fojc 的。大家还记不记得我们前面呢提到一个叫设置一个最小的暂停时间这样的一个概念对吧?如果我们设置的这个暂停时间过小的话, 默认呢是不是二百毫秒啊,还记得吧。那如果呢,比如你设置成二十毫秒的时候,那你想想我们每次呢在垃圾回收的时候呢,是不是这个让垃圾回收记这个可以发挥余地的,这个时间时代太短了,对吧?所以每次呢回收的这个 red 呢就比较少。那么如果此时呢,你 创建国家这个用户现成呢,这个新占用的这个空间呢,远大于我们这个锐震回收的这个速度的话呢,是不是就会触发我们这个叫 fojc 了。那因为你这个内存呢,迟早是不是会用完,那就触发这个 fojc。 那 fo j c 的话呢,它是一个独占式的,强度比较高的啊,单现成的这样一个特点 ok, 但是正常情况下的情况下的话呢,我们说都不会这个出现 fo j c 了。那那你这块呢,如果一旦出现以后呢,你需要呢进行一个系统的一个调优,那避免呢让它出现这个 fo j c, 那具有需要呢,具体来看一看这个代码那就 行。那这呢我是用一个图式的方式呢,给大家表示表达出来了。首先的话呢是年轻贷的 gc, 然后进入呢有年轻贷和这个并发标记环节。这个呢是虽然我们叫做老年代的并发标记环节,但是呢这个环节当中是也会出现年轻贷 gc 的啊,这大家注意。 然后呢,就是一个混合回收的过程,那这块呢是三个环节,也有可能会出现四个环节,就是这样多一个这样的一个套路是吧?好,这个图呢,应该是比较清楚的。然后接下来我们对刚才说的这个环节的话呢,几个过程,咱们整体上呢 进行一个说明。首先的话呢,我们说这个叫样 j c 是吧?这个样 j c 的话呢,就跟咱们前边介绍过的情况是一样子的,当我们这个年轻代的 e d m 区,这个要用尽的时候,就是当你要分配新的对象,发现空间不足的时候呢,我们要进行这个样 j c 了。 那今年的杨雷 c 在这个年轻在这个回收的时候呢,注意他是一个叫并行的独占式的回收器,收益器并行理解是吧,多个垃圾回收现成独占式 stop the word。 嗯,这样个场景,那他会暂停所有的这个应用进程啊,应用的现场 行。那么这呢跟咱们前面讲的这个内容又一样了。这个垃圾回收的时候呢,我们会这个清空这个一点元区对吧?把这个一点区的这个对象呢,是不是就存放到这个叫死歪歪区啊,就是存活的存放到死歪歪区,那是垃圾的话呢,这块就清理掉了对吧? 那么本身呢是在 svr 区呢,如果他达到那个预值默认的话呢,我们说是十五,就那个 a 值呗,默认达到十五的话呢,他就会存放到老年代。当然也有可能我们这个一点元区存放的是这个大对象, svr 区呢,也存不下,是不是直接呢也会放到这个老年代啊, 对吧?还有这样的情况哎,放到他这或者放到这,当然也有可能两个区域都会涉及到这个,跟咱们前面讲这个堆空间的那个内容啊,是一脉相承的,所以这块呢,大家并不陌生, ok? 然后当我们这个堆空间的,这是我们说的这个叫样 jc 是吧?第一个环节啊, 当我们这个堆空间的这个内存使用达到一定值的时候,堆内存呢,使用达到一定值的时候,咱们那会呢是不是看这个参数的时候呢,提到过这个问题,默认的情况呢,是不是百分之四十五啊,对吧?说一旦呢,当你达到这个预值百分之四十五的时候呢,我们就开始老年代的一个叫 并发标记过程,哎,老年代的一个并发标记过程,那这个标记过程的细节呢?咱们一会看啊,当这个标记完成以后,咱们就开始叫混合的一个回收过程,就是我们说的这个第三个环节叫混合回收对吧? 这个婚车回收这个过程当中呢,我们说这个哎,这 first 垃圾回收器,从老年代呢会移动存活的对象呢,放到这个空前的区域,就相当于我们进行老年代的回收了,你要还存活呢,我们就放到这空前区域,这呢相当于也是一个整理吗? 那这些空间区域呢,就成为了新的这个老年代的一部分了,和你现在不一样呢。老年代这个 jc, 嗯,跟其他这个垃圾回收器呢,还不太一样。 这个老年代这个回收,咱们以前讲呢,因为你是整块的一个老年代,所以我们是整体上进行的,是不是叫 major 这些啊?对,而我们现在的话呢,它主打的叫低延迟吗?那低延迟的话呢,因为我们分成了很 很多锐震,咱们前面已经说了好几次了,是不是只选择满足你那个暂停时间的情况下呢?我们去挑选那个价值比较高的锐震进行回收对吧?所以他只会扫描和回收其中一部分啊,这个锐震 啊,一部分这个锐震。那在这个过程当中,我们说老年代的锐震和年纪大的这个是可以一起被回收掉的,这叫混合回收吗?混合回收呢?还是一道这个新生代的一个回收啊。 行下边呢举了个例子,就这呢就是我们所说的一个正常的一个场景,正常的一个场景,比如说这有一个外服务器,这个外服务器的话呢,我们说最大的这个这个进程的这个内存呢,是四个 g, 每分钟呢,响应有一千五百个请求, 每四十五秒钟呢,我们就会重新分配大概两 g 的这个内存,哎,你看每四十五秒钟,因为我们进行过一次样 jc, 样 jc 的话,我们会回收很多的这个数据是吧,很多的这个空间,然后空出来了有两个 g 的两个 g b 的这个内存空间可以 去使用。 ok, 然后每三十一个小时的话呢,我们整个堆呢,这个使用率呢会达到百分之四十五,每三十一个小时百达到百分之三十五,四十五。然后我们开始呢进行老年代的一个标记,标记完以后呢,我们进行一个混合的一个回收 啊,混合的回收啊,这呢就属于一个正常的情况,如果呢你触发了这个 fojc, 而且还是比较频繁的出发这个 fojc, 大家这时候呢就需要呢去做我们这个先人参数的一些设置啊,你看内存空间设置的是不是合理 对吧,哎,这样那个场景 ok。 这呢就我们整体上呢对这样的几个环节呢进行一个介绍,大家呢首先呢就是先心里有数,然后的话呢,我们具体展开看一下这个第一个环节,第二环节和第三个环节他这里边的一些细节的问题啊。

好的,今天我们就一起来聊一下垃圾回收算法,话不多说,点个关注我们开始。那这边首先要点名的一点是,我们平时说的 cms、 g 等等,这些都是垃圾回收器,并不是垃圾回收算法。垃圾回收算法主要是垃圾回收器所使用的用来清理垃圾的一种方法。我们平时常见垃圾回收算法呢,主要有三种,标记清除、 拷贝以及标记压缩。首先是标记清除,标记清除这个算法它主要有两遍扫描,第一遍扫描就是把我要回收的内存区域给标记出来,就图中的黑色区域。 第二遍扫描是把这些已经标志为要回收内存区域给进行清理,也就是说我们把之前标志的区域清理掉,那标志清理方法有没有什么问题呢?我们可以看到会产生很多内存碎片,就比如说我这些内存是不连续的, 如果想整片分配的话,就分配不了了,那这种情况造成就是我很多空闲内存不连续,大对象可能找不到可以分配的空间。这就是标记清 清除算法所存在的问题。拷贝算法呢,他是将内存区域一分为二,然后只使用其中的某一块区域,当我其中一块区域放不下了,就把这块区域中存活的对象所占用这部分空间,就灰色区域集体拷贝到另外一半的内存中,并且在拷贝过程中把他们都紧凑的往前挪,变成连续的内存占用区域。 那这个拷贝算法解决我们上面这个内存碎片的问题,那有没有什么问题呢?问题也是存在的,就是他一开始就需要把内存压缩到原来的一半,因为他把内存一分为二嘛, 当存货对象比较多的时候,我们拷贝对象的效率会大大降低,因为他需要拷贝对象多,并且他会不断往前挪动。那第三种是标记压缩算法,那这个和我们开始看到的这个标记清除是比较接近的,只不过他解决了标记清除算法的内存碎片问题。 标记加速算法呢,也是两次扫描。第四扫描是把要回收的内存区域给标记出来,就图中的可回收的黑色区域。那第二次扫描呢,是把可回收 去清理掉,并且把存货对象的内存区往前移动,变成连续的内存占用空间。也就是说相比于标记清楚,他是先标记,然后再清除加移动对象,就是所谓的压缩,就把这些占用内存区域往前压,那标记压缩方法有没有什么问题呢?那也是有一定问题的, 因为相比于标记清楚,他多了一部移动对象内存这么一个动作,所以说他效率会相对低一点,因为他需要移动对象嘛,这就是所谓的鱼与熊掌不能兼得嘛,因为你要做的事情多了嘛。 ok, 我们简单总结一下,本期视频呢,我们讲了常见的三个 gc 算法,标记清楚拷贝以及标记压缩,每一个算法都有各自所存在的问题, 标记清楚呢,就内存碎片拷贝呢,就是存货对象多的时候,拷贝效率会变低,同时呢,他内存只能使用一半,标记压缩呢,则效率稍微低一点,因为他需要移动对象进行压缩。好的,本期的视频呢,就到这里,欢迎大家点赞、关注、收藏、留言,后续不迷路浪费时间不?


垃圾回收器之一的 r set、 c set 你了解多少呢?今天要讲的知识点你都知道吗?首先是 c set, c set 全真是 collection set, 它内部是一组可被回收的分区的集合,是堆中单独的一块区域, 实质存的是这些区域的信息,主要标识该区域的位置和归属。那这些可被回收区域呢?来自于一等区、 survivor 区,老年代。但要注意的是,它不会包含 humorous 这个区。 在质疑中呢, humorous 对象的回收通常不会单独成为一个 collective set 的目标。那当存在 humorous 对象需要被回收的时候呢?一般都会触发否止习,从而对整个堆进行垃圾回收。 那我们这边再回顾一下 g、 e 的分区,它会有一等区、 survivor 区、 o 的区以及 humorous 区。那这些分区呢,都是动态调整的。在 collection set 中呢,存活的数据会在 g、 c 的过程中呢,被移到另一个可用的分区。 c。 c 的占用的空间呢,是 不到整个堆空间的百分之一的。好的,我们再进阶一下。那 cc 的里面的区域集合是怎么选出来的呢?就有哪些区域会被放到这个 cct 里面呢?这些区域有个特征,就是通常会包含比较多的垃圾对象。那就一会根据一些启发式的算法和策略,动态的去选择一组区域,使得他们的垃圾对象比例比较高。换句话说就是回收这些区域是最有效果的。 那这些区域会被标记成凯尔顿 set, 在下一次回收过程中会被优先回收。通过选择高垃圾密度的序呢,进行回收可以减少全局停顿的时间,这也是之于实现可控垃圾回收时那个关键。好,我们再来讲一下阿 set。 阿 set 全称呢,就是 remember set, 它是每个 region 中都有的。注意它是维护在每个 region 中的。 它里面记录的是其他认证中的对象到当前认证的引用。就比如说我这个认证有个对象被其他认证中的对象引用了,那他记住就这个引用关系。那阿塞特的作用是什么呢?作用是在垃圾回收的时候,我们不用再扫描整个堆,就可以通过 这个阿塞特去找到谁赢了。当前分居中的对象,那 gc 的时候会判断要回收的对象有没有被引用,就是用到这个东西,他也是居呃,他也是居于高效回收的关键点,也是三色标记算法的一个依赖项。好,我们再进阶一下。那这边我们可以想一下阿塞特和我们之前讲的那卡表有什么区别呢? 首先卡表是单独的一张表,它并不是在每个 region 中的卡表,记录的是这个 cut 是不是 dirty。 单独看 cut 我们是并不知道具体的引用关系的。那综合来说的话,就是卡表记录的堆内存中对象引用的变化关系,也就是说是否 dirty。 而阿塞特呢?则是卡表中与跨 region 引用相关的部分, 里面存是具体的引用信息,通过战行者结合呢之一,能够实现增量式的垃圾回收,并优化跨区引用的追踪和处理。好,我们这边来补充一下,就是 c 赛特和阿赛特呢,它底层基本都是哈士赛特。 这边。最后我们再讲一下这种 cc 和阿赛的这种思想呢?是否可以在日常开发中学习,渐渐被使用呢?大家可以想想有没有什么例子?好的,本期的视频呢?就到这里,欢迎大家点赞关注、收藏、留言,或者是不迷路,让我们袭击不。