《垃圾回收的算法与实现》——GC复制算法
https://www.cnblogs.com/suolu/p/6654236.html
基本概念
- GC复制算法将堆分成From和To两个内存块,当From被占满时GC将From中的存活对象复制到To中,同时将From和To交换。
- 通过递归遍历GC root(即采用深度优先)复制存活对象,对于已经复制过的标记其COPIED字段。
- 复制过的对象将在From的对象的forwarding记录To中该对象地址,以便于其余引用了该对象的引用进行修改。
- 分配对象时将先判断From中连续可用空间是否够用(复制算法不存在碎片),如果不够则进行一次GC,还不够则分配失败。
优缺点
优点
- 吞吐量大,只需要遍历一次From空间Sweep需要遍历两次,而且只复制存活的对象。
- 高速分配,不需要通过空闲链表直接在连续的内存上进行分配。
- 没有碎片。
- 与缓存兼容,复制存活对象时采用深度优先算法使相关联的对象都在附近。
缺点
- 堆的使用效率低,必须分配一个To,其不能分配对象。
- 不兼容保守式GC算法,需要移动对象。
- 递归调用,复制对象的深度优先算法是通过递归调用实现的,递归将消耗栈等资源。
改进
Cheney的GC复制算法
针对递归
- 复制算法的To中增加scan指针,其指向To中已经复制过所有子对象位置。
- 首先将GC root直接引用的对象复制到To中,而后通过scan指针的移动对后续存活对象进行复制。实现了广度优先搜索算法
- 通过scan在To中的移动实现了一个隐式的FIFO队列。
- 取消COPIED字段,通过forwarding字段是否指向To区间来判断该对象是否已被复制。
- 优点在于取消了递归,缺点则是采用了广度优先算法使其与缓存不兼容。
近深度优先搜索方法
针对Cheney的复制算法中与缓存不兼容问题
- page:堆分隔成一个个页面的数组;local_scanf:每个页中搜索用的指针作为元素的数组;major_scan:指向未搜索完的页面开头;free:分块开头;
- 第一阶段从GC root中将其直接引用复制到第一个页中。
而后对每个对象按照类似深度优先算法,区别在于其原始深度优先算法每层一次只搜索一个对象而该算法则将同一层一次搜索完此处没懂,还有页占满的问题
多空间复制算法
针对堆利用率低
- 将堆分成多份,每次取其中的两个分别作为From和To,其余则采用Mark-Sweep算法。
- From总在To的右边的块中,每执行一次GC,From和To均向右移动一个块。
- 在GC时先进行标记阶段,当存活对象处于From时执行copy,当处于其余块时执行mark。
- 优点在于提高了堆的利用率,缺点则是引入了Mark-Sweep算法导致STW时间变长,分块得采用空闲链表
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2017-10-07 Spark Shuffle原理、Shuffle操作问题解决和参数调优
2017-10-07 Spark Streaming与Storm的对比及使用场景
2016-10-07 Linux下使用sendmail发送邮件