CMS垃圾回收器
什么是CMS垃圾回收器,CMS回收器的特点
CMS即Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的针对老年代的垃圾回收器。如果老年代使用CMS垃圾回收器,需要添加虚拟机参数-XX:+UseConcMarkSweepGC
CMS垃圾回收器GC过程暂停短,适合对时延要求较高的服务,用户线程不允许长时间的停顿的场景。但是容易造成严重的内存碎片化,且对CPU资源非常的敏感,无法处理浮动垃圾,可能出现Concurrent Mode Failure失败而导致Full GC产生。
CMS垃圾回收器的工作流程与原理
CMS垃圾回收器的工作需要经历初始标记、并发标记、重新标记、并发清除四个步骤。
- 初始标记
初始标记的对象为:
- 标记老年代中所有GC Roots引用的对象
- 老年代中被年轻代中存活的对象引用的对象。

由于需要对所有的对象进行标记,为了避免在标记过程中对象状态发生改变,所以需要Stop the world即停止所有用户线程,但是整个标记的过程耗时较短。
并发标记
从初始标记阶段找到GC Roots开始进行Tracing,找到所有的存活对象。
并发标记阶段会与用户线程同时进行,因此会有一些对象的引用状态发生改变。重新标记
标记在并发标记阶段引用发生变化的对象,如果发现对象的引用发生变化,则JVM会标记堆的这个区域为Dirty Card。
那些能够从Dirty Card达到的对象也被标记为存活,当标记完成后,这个Dirty Card区域就会消失。
该阶段是一个并发阶段,能够与用户线程同时运行,不会中断它们。并发清除
清除那些未被标记的对象回收内存空间。
G1垃圾回收器
什么是G1回收器,G1回收器的特点
G1回收器(Garbage First).可以通过-XX+UseG1GC.G1垃圾回收器以关注延迟为目标、服务器短应用的垃圾收集器。G1的设置原则是“首先收集尽可能多的垃圾”,因此G1并不会等内存耗尽或者快耗尽的时候开始垃圾收集,而是在内部采用了启发式算法,在老年代中找出具有高回收收益的分区进行收集。同时G1可以根据用户设置的暂停时间目标自动调整年轻代和总堆大小,暂停目标越短年轻代空间越小、总空间就越大。
G1的内存模型
G1采用自动分区(Region)的思路,将内存划分为一个个相等大小的内存分区,回收时则以分区为单位进行回收,存活的对象复制到另一个空闲分区中。由于都是以相等大小获得分区为单位进行操作,因此G1天然就是一种压缩方案。这些reding最后又被分别标记为Eden,Survivor和old,这里只是逻辑分区不是物理表示
。在这之外还有Humongous Regin,巨型对象分区,巨型对象会独占一个或多个连续分区,确定巨型对象分区空间需要扫描整个堆,因此应用程序应该避免生成巨型对象。
G1工作的流程
RSet的维护
RSet即已记忆集合。在串行和并行收集器中,GC通过整个堆扫描,来去确定对象是否处于可达路径中。然而G1为了避免整堆扫描时的Stop the world,它在每个分区记录了一个已记忆集合,内部类似一个方向指针,记录引用分区对象的卡片索引。当要回收该分区时,通过扫描分区的RSet,来确定引用本分区内的对象是否存活,进而确定本分区的对象存活情况。初始标记
初始标记负责标记所有能直接可达的根对象(虚拟机栈对象,全局对象,本地方法栈对象)。在初始标记过程之中需要暂停用户线程(Stop the world).G1一般利用年轻代STW时间段完成初始标记。初始标记是并发执行的,直到所有的分区处理完。并发标记
并发标记和应用线程并发执行,每个线程每次只扫描一个分区,从而标记出存活对象图。最终标记
最终标记是最后一个标记阶段。在该阶段中,G1需要一个暂停的时间,区处理剩下的SATB日志缓冲区和所有更新,找出所有未被访问的存活对象,同时完成存活数据统计。这个阶段也是并行执行的。筛选回收
该阶段主要进行Rset梳理,启发式算法会根据活跃度和RSet尺寸对分区定义不同等级,同时RSet数理也有助于发现无用的引用。参数-XX:+PrintAdaptiveSizePolicy可以开启打印启发式算法决策细节;整理堆分区,识别所有空闲分区,即发现无存活对象的分区。该分区可在清理阶段直接回收为混合收集周期识别回收收益高(基于释放空间和暂停目标)的老年代分区集合;无需等待下次收集周期。



