美文网首页
G1垃圾回收器总结

G1垃圾回收器总结

作者: imclient | 来源:发表于2020-03-01 15:49 被阅读0次

    1. 分代收集(Eden, Survivor0, Survivor1, Tenured按内存整块划分,连续的内存地址)

    内存默认分配:

    young: 1/3

    Eden: 8/10

    S0:1/10

    S1:1/10

    old: 2/3

    cms:

    初始标记(CMS-initial-mark) ,会导致stw;

    并发标记(CMS-concurrent-mark),与用户线程同时运行;

    预清理(CMS-concurrent-preclean),与用户线程同时运行;

    可被终止的预清理(CMS-concurrent-abortable-preclean) 与用户线程同时运行;

    重新标记(CMS-remark) ,会导致swt;

    并发清除(CMS-concurrent-sweep),与用户线程同时运行;

    2. 非分代收集(各个分区不是整块连续,非连续内存地址)

    G1两种GC:YoungGC、MixedGC,MixedGC之前会触发YoungGC;

    2.1 分区介绍:

    内存分为年轻代和老年代,年轻代还是Eden和S0+S1,老年代是Old和Humongous,默认会分2048个内存段,可以分别是不同的代,Humongous存大对象,

    如果对象大于内存段的一半,会分配到Humongous上,超过一个大小会分配到连续的Humongous上,也会优先被回收;

    2.2 概念介绍

    Card Table:

    Remembered Set: 每个内存段都对应一个RS,记住谁引用了我,指向card table中对应的entry,垃圾回收时能直接找到对应引用,不用扫描整个堆,

    年轻代段内只保存老年代的引用,因为youngGC时会扫描所有年轻代对象,同时发现其引用关系,老年代只保存老年代对象引用,

    老年代GC时Eden肯定是空的,都转移到S区了,G1会去扫描Survivor区,S区都是存的老年代的引用,能够获取到和老年代的引用关系,因此老年代只保存自己

    就够了;

    主要作用:回收单个内存段时,避免对整个堆的所有对象扫描,查看是否有引用;

    2.3 回收过程:

    不断新建对象到Eden区,Eden区满后触发YoungGC,只回收Eden和Survivor

    2.3.1 YoungGC:

    1.G1 Stop-the-word

    2.创建CS:回收集Collection Set(CS),需要被回收的内存分段集合

    3.扫描 GCRoot:

    4.更新RS:处理dirty card queue 中的card,更新RS,这时RS能够准确反应老年代对内存段中对象的引用情况

    5.处理RS:标记这些被老年代引用的对象,认为是存活对象

    6.复制对象:存活对象Eden到Survivor的过程,S区活的对象年龄+1

    7.处理引用

    2.3.2 老年代并发标记

    整个堆内存占用达到一定时(默认45%),会启动老年代回收;检测堆内存使用情况的时机是YoungGC后,或者Humongous对象分配之后;被标记过的对象

    引用改为null后,之前的对象会保存到一个队列中

    1。YoungGC Stop-the-word,回收后恢复应用线程

    2。开始老年代标记,并发进行

    3。重新标记 stop-the-world,重新标记队列中的对象

    4。回收百分之百为垃圾的内存分段,完成后恢复应用线程

    2.3.2 MixedGC

    过程同YoungGC,新生代和老年代同时回收,部分为垃圾的内存分段被计算出来,垃圾占比的分段比例越高回收的优先级越高,默认达到65%会被参与回收,老年代内存默认分

    8次回收;

    2.4 Full GC

    触发条件:G1回收过程中,堆内存太小导致复制的对象无空的内存段可分配

    相关文章

      网友评论

          本文标题:G1垃圾回收器总结

          本文链接:https://www.haomeiwen.com/subject/lyeckhtx.html