G1垃圾回收器总结

2020-03-01  本文已影响0人  imclient

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回收过程中,堆内存太小导致复制的对象无空的内存段可分配

上一篇 下一篇

猜你喜欢

热点阅读