首先说下G1
先说下G1比较特别的内存分配方面,
它把堆内存划分为一个一个固定大小的region,当然,这些region也有eden,survivor,old和humomous之分,前三个和之前的cms分代回收的概念一样,humomous主要用来存放大对象,可以一次连续申请几个region作为一个大对象的存放空间
G1回收也划分为几大步骤
首先,初始标记,这个会stop the world,和cms一样,也是标记gcroot的直接引用的对象
然后,并发标记,也是根据可达性分析算法把引用到的对象标记一遍,利用SATB将并发标记期间产生的新的引用对象存放到remeberset中
接着,最终标记,stop the world,将remeberset中的引用都标记一遍
最后,筛选回收,这里就是G1的特色了,他会维护一张表记录每个region回收的收益比,然后根据这个收益比进行排序,再根据设置的最大回收时间进行评估优先处理多少region从而筛选出要回收的region。
ZGC
首先也是讲下内存分配的特点,ZGC暂时没有分代这一说,也是按region对堆进行分块
但是region只分为小,中,大region
回收分四个大步骤,都是并发执行的,在这四个大步骤之间会有近乎可忽略的stw
并发标记,开始前就会有跟之前一样的初始标记,stw,也一样,对初始标记中的gcroot的直接引用进行可达性分析,标记,但是此时的标记已经不是像之前的三色标记法了,而是才用color points,翻译是颜色指针,其实就是利用64位系统中一个指针的大小是64位的特性,但又由于标识内存地址用不了那么多位,就用比标识内存地址的位上面的空闲的高为中高4位用来标识标记
并发重分配预备,就是筛选出要重分配的region
并发重分配,就是将回收的region中的非垃圾对象复制到另外的空闲region中,并修改颜色指针的状态,并在原来的region中维护一个映射表,保存原来的region的非垃圾对象移动到新的region的地址 引用.当外部有访问被分配的对象的时候,通过读屏障识别出颜色指针的状态被修改,那么就通过原来region的映射表找到 新region的地址,这就是指针的"自愈"特性
并发重映射,就是将颜色指针的引用更新为原来的对象移动到的新region对应的地址引用,但是由于颜色指针有自愈特性,所以这一步并不急于完成,所以将此步和下一轮的并发标记同时进行,反正都是要遍历引用,一举两得.