G1 垃圾收集器
年轻代: 老年代
Serial 单线程的复制算法 Serial Old
pawNew 是Serial的多线程版本 CMS (最大降低了,单次垃圾的收集时间)
Parallel Scavenge 关注的是吞吐量 Parallel Old
之前的内存结构:
G1 的内存结构:每一个region 是 1-32M
那如果大对象来了,要怎么放呢?
-
0.5region <= 对象 <1 region,这个对象会直接存储在 O区,并标记为H区(超大对象区)
-
对象>1 region,会申请多个连续的H区来存储这个对象
Rset
一个Region 有一个Rset : 记录其它Region引用当前Region对象
Cset
本次GC需清理的Region集合
YGC:
采用复制算法,将E和S(from)区 复制到S(to)区,图中比较小的绿色就是 S(to)区
没有单独的Old区GC,在old gc的时候,同时也把young区进行了gc。 因此有一个MixGC
并发标记过程:
1. 初始标记阶段: 标记从根节点直接可达的对象。 这个阶段是STW,并且会触发一次年轻代GC
2. 根区域扫描(RootRegionScan): ????
Rset作用有哪些: 有了Rset 只需要查看所有Y区region的Rset 就知道哪些O区region跨代引用了,避免了扫描整个O区。
G1 提高效率的点有哪些:
1. 重新标记时X区域直接删除
2. Rset 降低了扫描时间
3. 重新标记阶段 使用了SATB 速度比CMS快
4. 清理过程为选取部分Region进行清理,提高了清理的效率。
对比CMS,有哪些不同?
1. region化的内存结构,采用复制清理方式,避免了内存碎片
2. SATB 速度更快
3, 初始标记,并发标记,重新标记,并发清除四个阶段很像,但是G1 中有很多标记region的操作,并借助Rset进行了范围的缩小,提高了并发标记的速度。
初始标记和YGC 的STW一起,提高了效率;
并发标记因为rset的设计,扫描范围缩小了,提高了效率
重新标记使用了SATB提高了效率
清理虽然造成了STW,但是复制使内存紧凑,避免内存碎片。同时只清理垃圾较多的region,最大限度降低了STW时间。
遗留问题:
1. G1中的记忆集是怎么实现的
首先产生跨代引用的场景是发生YoungGC的过程。此时新生代的对象会开始寻找根,看看自己是否属于根可达对象,从而判断自己是否是垃圾。
但并不是所有老年代都会引用着新生代的对象,那么相对频繁的YoungGC,每次都从根节点遍历一次,效率就会被严重影响。
卡表将整个老年代分成了多个层级,card[0]、card[1]、card[2]。如果某个card区域中的老年代对象引用着新生代的对象,那么就被叫做脏卡。当YoungGC发生时,某个新生代的对象发现其GCRoots在老年代,并进行跨代寻找的时候,只需要在对这些脏卡中的GCRoots,使用可达性分析算法,判断是否存活即可。
每个Region中都存在一个Hash Table结构的记忆集,Key为其他Region的起始地址,Value是其他Card Table卡表的索引集合。
原来卡表指向的是卡页的内存地址段,代表我引用了谁,每个Card覆盖一定范围的Heap,
现在的记忆集,代表着谁引用了我,因此收集的过程会更复杂一点,并且需要额外的10%-20% 的堆内存空间来维持。
维护记忆集的方式也和卡表类似,通过写屏障来实现。
引入标准介绍:
卡表是:我引用了谁,CMS中,用于减少遍历Old区域
记忆集是:谁引用了我,是一个Hashtable,key是region起始地址,value是一个集合,对应的是卡表的index,然后就可以找到对应的脏表。
2. 重新标记的时候,为什么SATB快。 (原始快照)
之前CMS讲过了,漏标的情况是:
灰色断开对象,然后黑色又连接上了这个对象,但是这个对象是白色的,因此在重新标记的时候并没有被标记,此时出现漏标情况。那如何搞定呢?
具体流程:
1. 开始时生成一个快照。标记存活对象
2. 在并发标记的时候所有被改变的对象入对, 在写屏障里把所有旧的引用所指向的对象都变成非白色的。
3. 可能会存在浮动垃圾,将在下次被收集。
例如 A.b =B,C.b = null 在并发标记中 发生了 A.b = null,C.b =B。 那么这个时候由于旧的引用A所指向的对象是B,所以将B标为非白。
那如何找到GC过程中新分配的对象呢?
SATB再重新标记环节只需要去扫描那些被入队的引用,并配合Rset来判断当前对象是否被引用来进行回收;
而增量更新还需要再扫描一遍;
4. mix GC和young gc 到底是个怎么样的流程:
young GC 回收的是所有年轻代的Region。当E区不能再分配新对象时就会触发。采用复制算法将E区和S(from区)复制到 S(to)区。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构