垃圾回收算法主要分四大类,
分代收集算法,就是分老年代,年轻代
标记-复制算法,就是将不是垃圾的标记出来,标记完成后将这些标记的对象复制到另外一个空闲区域,然后将原本的区域全部回收
标记-清除算法,就是将不是垃圾的标记出来,然后将没有标记的对象都回收,会产生内存碎片
标记-整理算法,就是将不是垃圾的标记出来,然后将标记的对象全部向首端空闲部分移动使标记的对象都向首端紧挨着,然后再将右边的空闲区域都回收掉
而将算法进行具体实现的就是垃圾回收器了
我们这里先介绍经典的垃圾回收器,Serial,Parallel,ParNew,CMS
Serial同时也有SerialOld就是分别应用在年轻代和老年代的垃圾收集器 ,顾名思义,单线程,串行化回收,回收期间stop the world
Paralle同时也有Parallel,也是分别应用于年轻代和老年代的垃圾收集器,在Serial基础上新增了多线程,也就是多线程并发回收垃圾,但是回收期间也是stop the world
ParNew,也是多线程回收垃圾器,主要应用于年轻代,和CMS配合使用
CMS 主要应用于老年代,分五个阶段
初始标记,stop the world,只标记直接引用对象,比如某个root对象直接引用的对象
并发标记,从一开始标记的对象开始进行可达性分析标记,与用户线程同时 进行
重新标记,对并发标记期间,漏标的对象进行处理,stop the world
并发清理,对未标记的垃圾对象进行清理,与用户线程并发执行
并发重置,清理完成,将标记进行重置,这里的标记涉及到三色标记法
三色标记法分为三种颜色, 黑,灰,白
黑色表示该对象已经进行可达性分析过,不会再分析,也就是它的所有直接引用都已经分析过了
灰色标识该对象已经在分析,但是部分直接引用尚未分析
白色标识完成没有分析到
按正常情况,白色没能到达,证明他是没有被引用到的对象,也就是垃圾对象,是可以回收的
但是,在并发标记的期间可能在黑色对象产生新的引用指向白色对象,这样子按照三色标记法我们是不能标记到新的引用的。所以我们在重新标记期间进行处理,这里有两种处理方法,一种是SATB原始快照法,一种是增量更新法
CMS采用的是增量更新法,就是在并发标记期间,把黑色对象产生的新的引用记录到集合中,在重新标记期间把这部分引用重新标记为黑色,也就是相当于挽救了这部分对象了
G1采用原始快照法,就是在并发标记期间将要进行置空的对象的原始引用记录到集合中,在重新标记期间再把这些引用对应的对象重新标记为黑色,我自己感觉就是 用冗余解决漏标问题
而不管是SATB,还是增量更新,进行记录引用过程中都涉及到一个读写屏障问题,其实就是在进行新增引用或者置空引用的操作前后进行额外的操作,这有点类似于代理对应对方法进行增强的感觉,在SATB和增量更新中就是在进行新增引用或者置空引用的代码前后新增一些记录引用到集合的代码,这就是所谓的写屏障了.