3.2经典垃圾收集器

7中经典垃圾收集器:https://blog.csdn.net/weixin_43696529/article/details/104884777

低延迟收集器

8.Shenandoah

与G1有三个明显不同

  支持并发的整理算法

  不使用分代收集

  摒弃了记忆集,改用连接矩阵(Region N 有对象指向Region M ,则在表格N行M列中打标记)

回收过程

  初始标记:与G1一样,标记所有与GC Roots直接关联的对象,仍是Stop the World

  并发标记:与G1一样,便利对象图,标记全部可达对象,与用户线程并发

  最终标记:与G1一样,处理剩余的SATB扫描,计算回收价值最高的Region

  并发清理:清理一个存货对象都没有的Region

  并发回收:把回收集的存活对象复制进其他Region中,通过读屏障被称为Brooks Pointers 的转发指针来解决并发过程中用户对对象的读写访问

  初始引用更新:并未有实际操作,是为了确保所有回收线程已经完成了分配给他们的对象迁移任务,,会产非常短暂的停顿

  并发引用更新:按照物理内存地址顺序,先行搜索引用类型,把旧值改为新值

  最终引用更新:修正存在于GC Roots中的引用,最后一次停顿,与GC Roots数量有关

  并发清理:回收集中已无寻获对象,并发清理这些Region对象。

转发指针:在原有对象布局的最前面同意添加一个新的引用字段,正常情况下,指向自己

  问题:

    多线程并发写入,1.复制新副本2.用户更新对象字段3.更新转发引用指针为新地址以上顺序会导致问题,通过比较并交换(Compare And Swap ,CAS),保证并发时对象的访问正确性

    每次访问会带来一次额外的转向开销,高运行负担使得吞吐量下降(弱项,即运行时间下降)和低延迟时间(强项)

9.ZGC

  主要特征:

    基于Region内存布局

    使用读屏障,染色指针和内存多重映射技术实现并发的标记—整理算法

    以低延迟为首要目标

  Region动态性

    小型Region:固定为2MB,放置小于256KB的小对象

    中型Region:固定为32MB,放置大于256KB小于4MB的对象

    大型Region:容量不固定,可动态变化,必须为2MB的整数倍,放置4MB或以上的大对象,每个大型Region只存放一个大对象,实际容量完全有可能小于中型Region,最小低至4MB

  并发整理算法实现:染色指针技术

    对象头存储额外的数据,如哈希码,分代年龄,锁记录等。

    标记阶段三色标记:标记在对象头(Serial),与对象独立的数据结构(G1,ShenAndaoh用1/64堆大小的BItMap)

    ZGC直接把标记信息记在引用对象的指针上

    

  优势:

    某个Region的存活对象被移走之后,Region能立即被释放和重用掉

    减少垃圾收集的内存屏障使用数量(ZGC不支持分代收集)

    染色指针可以作为一种可扩展的存储结构记录更多与对象标记,重定位过程相关的数据

  内存多重映射技术

    染色指针中的标志位看作地址分段符,通过Linux系统调用mmap将标记位(001,010,100)三种地址空间映射到同一地址上,使三种地址解析后都指向同一地址

    

  回收过程:

    并发标记:与G1,Shenandoah一样,便利对象图做可达性分析,会更新染色指针中的Marked0,Marked1标志位

    并发预备重分配:统计要清理的Region组成重分配集,重分配集只决定了里面的存活对象会被复制到其他Region中,里面的Region会被释放,不能说回收是针对这个集合里的Region进行,因为标记过程是针对全堆的,JDK12的ZGC中开始支持的类卸载以及弱引用的处理,也是在这个阶段中完成的。

    并发重新分配:重分配集中的存活对象复制到新的Region上,并为重分配集中的每个Region维护一个转发表(记录就对象到新对象的转向关系),如果此时用户线程访问重分配集中的对象,访问被内存屏障截获,根据Region上的转发表将访问转发到新的对象上,并修正更新该引用(自愈),只要Region复制完毕就可以释放重新分配对象,未更新的指针一旦被使用可以自愈

    并发重映射:修正整个堆中指向重分配集中旧对象的所有引用。因为可以自愈,所以ZGC把它合并到了下一次垃圾回收时的并发标记阶段完成(节省了一次遍历对象图的开销)

  Epsilon收集器

  收集器权衡

    应用程序关注点

    运行程序的基础设施

    JDK的发行商,版本号

  虚拟机及垃圾收集日志

  垃圾收集参数总结

  内存分配及回收策略

    对象优先在Eden分配

    大对象直接进入老年代

    长期存货的对象进入老年代(对象年龄计数器,存放在对象投中)

  动态对象年龄判定

    Survivor中相同年龄的对象大小总和大于Survivor的一半,年龄大于或等于设定年龄(-XX:MaxTenuringThreshold)的可以直接进入老年代

  空间分配担保

    大量对象存活,Survivor存不下,把Survivor无法容纳的对象直接送入老年代

    检查老年代最大可用连续空间是否大于新生代所有对象总空间,如果成立,一次Minor GC 可确保时安全的,不成立则查看是否允许担保失败(-XX:HandlePromotionFailure),

    若允许检查老年打连续可用空间是否大于历次晋升到老年代的平均大小,若大于,进行一次Minor GC,若小于,改为进行Full GC。

    如果连续可用空间大于历次晋升老年代平均大小,还是Minor Gc失败,则重新进行Full Gc,这样停顿时间就更长了(因为绕了一圈),但通常开启-XX:HandlePromotionFailure,避免频繁Full Gc。

原文地址:https://www.cnblogs.com/zhaosong-0102/p/13031977.html