十种GC垃圾回收器

    科技2025-08-31  21

     

    分代

    serial和serial old

    1.serial和serial old <!--jdK3,4的时候使用的--> 单线程执行,串行

    serial(年轻代,copying)   :   单线程,需要gc时会停止工作线程,stw(stop-the-world) ,gc完之后在继续工作。 serial old(老年代 mark-sweep/mark-compact) : 单线程,当需要gc的时候,需要停止工作线程,stw,gc之后继续工作 ​ 缺点:单线程,stw时间会很长,内存越大越不适用

    parallel Scavenge 和 Parallel old (ps,po)

    jdk1.8默认回收器。调优会可能从pspo-> cms,g1等等

    ps:(年轻代,copying) : 多个gc线程,当需要gc的时候,也需要stw,gc之后才能在继续工作 ​ po(老年代,mark-compact)   : 多线程,当需要gc时, stw,gc后继续工作 ​ 缺点:gc stw,多线程资源开销

    ParNew 和 CMS

    ParNew (年轻代 coping): 多个gc线程,stw     和ps一样。 ​ CMS (老年代 mark-compact):大致会分为4个阶段。 ​ 初始标记。(工作线程还是会stw,在初始标记阶段只找到根上的对象,然后就恢复工作线程) ​ 并发标记。 (工作线程和gc线程会共同进行,底层使用的三色标记法。CMS解决方案就是会根据内存写屏障将黑色对象变为灰色,继续跟踪下去标记。因为并发GC线程,所以就会又ABA问题(第一个线程标记完子关系会变成黑色,第二个线程扫描的时候可能因为对象又引用了别的子关系,会变成灰色,但是第一个线程标记完之前的关系后又变成了黑色)) ​ 重新标记。(所以cms的remark阶段就会从头扫描一遍。) ​ 并发清理   然后进行清理垃圾 ​ 缺点:当CMS碎片话越来越严重的时候,CMS会使用SerialOld来清理老年代,也就是单线程并且stw.

     

    不分代

    g1

    g1 (三色标记法,标记清理算法) 和CMS类似。对三色标记法的解决方案不一样,适合大内存。比如堆大于6-8G

    G1解决方案:SATB   :灰色对象指定的标记消失的时候,会把这个引用标记推到GC的堆栈,保证GC扫描能再次扫描到,再次扫描只需要扫描那些region引用到该region。但是占空间,region种还有百分之20左右记录着谁引用的我。 缺点:空间占用资源大。

    zgc

    (jdk11 使用的颜色指针来判断该对象的状态,使用了读屏障)

    每一个引用在64位机器上占用的都是64位,在ZGC使用引用的时候只用了其中的42位,来代表指向某个对象的真正地址,高18位没用,中间有4位代表指向的这个对象的状态 Zgc能管理4T的内存(2的42次方),最大能管理16T的内存(2的44次方)。

    Shenandoah (jdk11)

    使用了读屏障,转发指针

    Epsilon

    ( 只做内存分配而不做内存回收(reclaim) )

    Processed: 0.011, SQL: 8