论文解读:从Dijkstra的On-the-Fly到Go的三色标记算法,并行垃圾回收的起源

news2024/9/20 22:54:07

我们经常听到关于垃圾回收的说法是,某种垃圾回收算法是一种特定语言特有的,容易理解成,垃圾回收的算法跟特定编程语言是绑定的,但是仔细想想,垃圾回收器是一种分配和管理内存的机制或者程序,内存管理跟语言本身是没有必然联系的,只是语言运行时实现时的一种策略选择。

更严格来说的,其实不仅仅是垃圾回收策略,一些语言的语法特性,也不是某种语言专属,语言的实现者完全可以通过组合,自己选择自己偏好的策略,发明更多的语言或者特定语言的方言;背后的本质是类型、文法和语法完备性的设计、运行时内存管理、内置函数调用,只要有合适的编译器和规则,就可以将任何语法转换成另外一种。

三色标记和并行垃圾回收,最早是在Golang中接触到,经常被认为是跟Go语言绑定的,其实这种颜色标记,早在半个世纪之前,就已经被著名的计算机科学家Dijkstra提出,通过论文On-the-Fly Garbage Collection: An Exercise in Cooperation,我想更详细的了解,并行垃圾回收的历史,是如何开始和发展的。

图片

并行垃圾回收的起源

这篇论文提出了一种新的并行垃圾回收方法,称为“On-the-Fly Garbage Collection”。这种方法特别适用于多处理器环境,在不停止程序执行的情况下进行垃圾回收。

多处理器系统的出现为并行处理垃圾回收任务提供了可能性,但需要解决并发过程中的同步和互斥问题。论文强调了最小化进程间互斥和同步约束的重要性,并展示了一种将垃圾回收任务分配给辅助处理器执行的方案。

算法通过将标记和清除过程交替进行,使得垃圾回收器(Collector)和主计算程序(Mutator)可以并行工作,从而避免了之前垃圾回收中的长时间暂停。

问题定义和回收的粒度

论文首先引入了“局部变量”和“共享变量”的概念,说明了并发操作中共享变量的处理问题。为了确保并发操作的正确性,文章提出了“原子操作”的概念,并定义了“粗粒度”和“细粒度”操作的概念。粗粒度操作易于证明正确性,但需要更强的互斥措施;细粒度操作则可以更好地利用并发性,但证明其正确性更为复杂。

文中将问题简化为维护一个有向图,并定义了可达节点、数据结构、垃圾节点等概念。

为了简化问题,论文对垃圾收集问题进行了以下两个简化:

1. 引入特殊根节点“NIL”,将缺失的边表示为指向“NIL”的边。

2. 将自由列表视为数据结构的一部分,并将自由节点链接到特殊根节点上。

通过这两个简化,问题被归结为两种类型的操作:重定向可达节点的出边指向另一个可达节点,以及将自由节点从自由列表中移除。

文中还定义了两个正确性标准:垃圾节点最终会被回收,垃圾回收是收集器唯一的结构修改。

粗粒度和细粒度解决方案

文中的解决方案,是基于不变式的策略,通过保证几种不变式不被破坏,保证垃圾回收正确性。

不变式P1:没有边从黑色节点指向白色节点。

不变式P2:对于每个可达的白色节点,都存在一条传播路径指向它。

不变式P3:只有Mutator最近放置的边可能从黑色节点指向白色节点。

第一个粗粒度解决方案

第一种解决方案首先是一种粗粒度的解决方案,其中垃圾收集器通过标记可达节点并回收不可达节点来清理垃圾。

为了保持数据结构的一致性,垃圾收集器引入了“灰色”节点表示部分标记的节点。垃圾收集器分为标记阶段和回收阶段,标记阶段将所有可达节点标记为黑色,回收阶段将所有未标记的节点回收并移除其标记。

在方案中,Mutator的操作是M1,重定向可达节点的出边指向另一个可达节点,并标记新目标节点为灰色”。Collector的操作是C1,标记灰色节点的所有后继节点,并将灰色节点标记为黑色。

这种解决方案的局限性是因为突变器可能在进行标记阶段时修改数据结构,导致收集器无法识别新的垃圾节点,因此无法保证Mutator引入的垃圾节点在下一个收集周期被回收。

第二个粗粒度解决方案

第一个解决方案中,垃圾收集器需要在引入新边之前标记目标节点,这导致了额外的开销。为了解决这个问题,论文提出了第二个粗粒度解决方案,其中垃圾收集器不再保持不变式P1,“无黑到白边”的约束,而是保持“每个白色可达节点都存在一条无C-边的传播路径”的约束,其中C-边是垃圾收集器标记阶段检测到的灰色节点的出边。垃圾收集器通过重定向可达节点的出边来保持这个约束,并将自由节点从自由列表中移除。

这种方案中,Collector的操作跟方案一是一样的,Mutator的操作则改成了M2,标记之前重定向的边的目标节点为灰色,然后重定向可达节点的出边指向另一个可达节点。

通过引入不变式 P2 和 P3,解决方案二能够保证Mutator引入的垃圾节点在下一个收集周期被回收。这是因为方案二限制了黑色节点指向白色节点的边数,从而确保收集器能够在下一个收集周期识别新的垃圾节点。

细粒度的解决方案

细粒度解决方案,是在第二种粗粒度方案的基础上发展出来的,将Mutator的操作M2和Collector的操作C1拆分成更细粒度的原子操作,进一步实现了更精细化的并发控制。

粗粒度原子操作M2拆分成两个原子操作。

  • M2.1: 在修改对象引用之前,首先标记引用的目标。

  • M2.2: 将指向一个可达节点的引用重定向到另一个可达节点。

粗粒度Collector操作C1被拆分为五个原子操作,其中包括对节点的阴影操作和将节点标记为黑色。

进一步简化为两个关键的阴影操作:

  • C1.la: 标记节点的左后继节点。

  • C1.3a: 标记节点的右后继节点。

细粒度Collector的操作与Mutator的操作是可交换的,即Mutator可以并发地执行而不会影响Collector的正确性。

为了证明这种细粒度解决方案的正确性,作者引入了更强的关系,并定义了“C-边”的概念,以描述在标记过程中检测到的边缘。

P2a 表明每个根节点都是灰色或黑色的,对于每个白色可达节点,存在一条不包含 C-边的路径通向它。

P3a 表明最多存在一条“黑到白”的边或一条指向白色节点的C-边,这种边的存在表明修改器正在进行特定的重定向操作。

细粒度的解决方案提供了更精细的并发控制和效率,但是需要更复杂的代码和更仔细的设计,从而增加了开发成本;相对而言第一种粗粒度的解决方案,实现比较简单,但是效率较低;通过引入较弱的不变式,第二种粗粒度解决方案性能有所提升。在实现的时候,应该根据具体应用场景和需求来实现。

其实不仅仅是垃圾回收器的开发中需要根据具体的需求权衡取舍,平时业务开发中,也是一样的,引入并发可以提升程序性能,但是要通过引入锁或者其他同步机制,保证数据一致性,粗粒度的锁,会影响并发的性能;而引入更细粒度的并发控制机制,可以精细的控制,从而提高效率,但是这样的实现,代码也会变得更加复杂。

着色标记和传播路径

论文中的高效并发处理,依赖于Collector和Mutator的协作机制。

Collector执行垃圾回收操作,即识别并回收垃圾节点;并且也会维护节点的颜色状态。

Mutator负责修改对象引用,它为新对象分配内存空间,改变对象引用,读取或者修改对象的属性。它会修改图结构,即重定向可达节点的边;同时根据重定向操作更新节点的颜色状态。

Mutator和Collector之间的读写操作被设计成互不冲突,因此可以并发执行。Collector只会读取节点的颜色和边信息,而不会修改它们。Mutator只会修改节点的颜色和边信息,而不会读取它们。

Mutator可以随时修改图结构,而Collector可以随时执行标记阶段。由于读写操作互不冲突,因此不会出现数据不一致。

当Mutator创建一个新对象时,它被标记为黑色(因为它是新创建的,显然是可达的)。当Mutator修改图结构时,它会更新节点的颜色状态。如果Mutator将一个白色节点的边重定向到一个黑色节点,则该白色节点会被标记为灰色。如果Mutator将一个黑色节点的边重定向到一个白色节点,则它会首先将之前重定向的节点的目标节点标记为灰色,然后再进行重定向。

Collector负责执行标记阶段,将所有可达的节点标记为黑色。在标记阶段,Collector会忽略灰色节点,因为它们尚未被完全标记。当Collector完成标记阶段后,所有白色节点都是不可达的,也就是垃圾节点。

着色标记机制的基本原理

论文中提到的着色标记机制是垃圾回收算法中的一种常见技术,用于识别图中可达和不可达的节点。它通过将节点标记为不同的颜色(例如白色、灰色和黑色)来追踪节点的可达性状态。

基本原理和步骤如下:

  1. 初始状态:所有节点都是白色,表示它们尚未被访问。

  2. 标记阶段:从根节点开始,将它们标记为黑色,并将它们的相邻节点标记为灰色。

  3. 传播阶段:对于每个灰色节点,将其相邻的白色节点标记为灰色,并将自身标记为黑色。

  4. 循环:重复步骤 3,直到没有灰色节点为止。

Collector根据当前阶段是回收还是标记,执行特定的操作;而Mutator可以并行的在两个阶段,执行自己的操作,它们的运行可以保证回收的准确性,而且通过同时运行程序和回收,大大提高了系统的效率。

论文解读:从Dijkstra的On-the-Fly到Go的三色标记算法,并行垃圾回收的起源icon-default.png?t=N7T8https://mp.weixin.qq.com/s/2Y262y0mPkCXsKrgnKu-fg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2058838.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微分方程(Blanchard Differential Equations 4th)中文版Section2.3

阻尼谐振子 在本节中,我们将描述一种解析技术,它适用于本书中最重要的模型之一——阻尼谐振子。这一二阶微分方程用于建模各种现象,如质量-弹簧系统、电路理论中的RLC电路,以及人体的血糖调节系统。 例如,考虑汽车的悬挂系统。它可以平滑崎岖道路上的颠簸,并帮助保持轮…

告别U盘:看医院如何挑选高效安全的文件摆渡系统

基于法规要求和自身安全管理需要,医院普遍使用网闸,将网络隔离为院内网、院外网。网络隔离后,医院各科室部门仍存在频繁的网间数据交换需求,需要文件摆渡系统进行内外网数据的安全交换。具体交换场景如下: 1.影像科&am…

iOS Native与JS通信:JSBridge

文章目录 一、简介二、JS 调用 Native1.使用 URL Schemea.UIWebViewb.WKWebView 2.使用 JavaScriptCore (iOS 7)3.使用 WKWebView 和 WKScriptMessageHandler (iOS 8) 三、Native 调用 JS1.使用 UIWebView2.使用 WKWebView3.使用 JavaScriptCore (iOS 7) 一、简介 对于移动应用…

江西学术会议:第五届计算机、大数据与人工智能国际会议

第五届计算机、大数据与人工智能国际会议(ICCBDAI 2024)将于2024年11月1日-3日在江西景德镇召开。本届会议由景德镇陶瓷大学主办,西安交通大学、暨南大学、南京邮电大学、景德镇学院、ELSP(爱迩思出版社)、ESBK国际学术交流中心、AC学术平台协…

ctfshow之web29~web51

目录 web29 题解: web30 web31 web32(32~36) web33 web34 web35 web36 web37 web38 web39 web40 web41 web42 (42~51) web43 web44 web45 web50 web51 web29 前瞻知识: isset() …

【sgCreateReadonlyForm】自定义小工具:敏捷开发→自动化生成只读表单代码片段脚本(无需列表展示数据,多用于查看某一条数据记录)

sgCreateReadonlyForm源码 <template><!-- 前往https://blog.csdn.net/qq_37860634/article/details/141389231 查看使用说明 --><div :class"$options.name"><div class"sg-head">只读表单生成工具<el-dropdown:show-timeo…

8.20 roles的基本用法+使用剧本安装nginx

安装nginx并更改其端口 创建目录 mkdir /etc/ansible/playbook 编辑配置文件 vim /etc/ansible/palybook/nginx.yml --- - hosts: s remote_user: root tasks: - name: 卸载httpd yu…

人工智能 | 结对编程助手GithubCopilot

简介 GitHub Copilot 是一款 AI 结对程序员&#xff0c;可帮助您更快、更少地编写代码。它从注释和代码中提取上下文&#xff0c;以立即建议单独的行和整个函数。GitHub Copilot 由 GitHub、OpenAI 和 Microsoft 开发的生成式 AI 模型提供支持。它可作为 Visual Studio Code、…

智慧水务平台:数智化驱动,‌实现管理全面升级!‌

智慧生产体系聚焦水务行业的生产环节,涵盖水源管理、水厂管理、生产调度、二次供水管理等各个环节。对各生产环节的实时生产数据和设备运行参数进行监测,并提供报警、日常运维、能耗分析、流程优化,为水务生产管理的成本压降、效率提升、安全保障、服务优化提供支撑。 智慧管网…

Echarts添加水印

如果直接说水印,很难在官方找到一些痕迹,但是换个词【纹理】就能找到了。水印就是一种特殊的纹理背景。 Echarts-backgroundColor backgroundColor 支持使用rgb(255,255,255),rgba(255,255,255,1),#fff等方式设置为纯色,也支持设置为渐变色和纹理填充,具体见option.colo…

哪个牌子的开放式耳机性价比高?五款地表最强机型推荐!

在我们的日常生活中&#xff0c;街道、地铁车厢或公交车等地方常常充满了噪音&#xff0c;这些杂音不仅可能扰乱心情&#xff0c;还可能对我们的听力造成潜在的伤害。在这样的环境下&#xff0c;如果想要享受音乐或追剧&#xff0c;同时又能保持对周围环境的警觉&#xff0c;开…

充电宝哪个品牌好?360度全方面测评热门款充电宝

在这个智能手机、平板电脑等移动设备普及的时代&#xff0c;充电宝已成为我们日常生活中不可或缺的伴侣。无论是在通勤途中、旅行出行&#xff0c;还是在户外运动时&#xff0c;充电宝都能为我们的设备提供源源不断的电力支持。然而&#xff0c;市场上充电宝品牌众多&#xff0…

c++开发,下载安装Boost库并检测是否安装成功

c开发&#xff0c;下载安装Boost库并检测是否安装成功 系统说明下载Boost库安装测试验证 系统说明 win10系统 下载Boost库 从官方网站下载&#xff0c;点击版本号 进去后选择windows系统的下载 安装 第1步 将下载后的压缩包解压到你想存储的文件夹中&#xff0c;比如我这里…

自主身份:Web3如何重新定义个人数据所有权

随着数字时代的快速发展&#xff0c;个人数据成为了一种新型的资产&#xff0c;深刻影响着我们的生活。然而&#xff0c;在Web2时代&#xff0c;个人数据往往被科技巨头所掌控&#xff0c;用户在享受互联网服务时&#xff0c;无意中失去了对自己数据的控制权。Web3的到来&#…

Java 调整字符串,验证码生成

package text7;public class ZiFanz {public static void main(String[] args) {//1.定义两个字符串String strA "abcde";String strB "deabc";//2.abcde->bcdea->cdeab->deabc旋转字符串//旋转并比较boolean result cheak(strA, strB);System…

时间序列分析中的特征提取

一、说明 在多变量时间序列分析期间&#xff0c;数据包含随时间推移测量的多个数据。为了管理模型性能&#xff0c;建议进行特征提取&#xff0c;以使模型的数据点更加紧凑。 二、时间序列的挑战 2.1 特征提取 仅选择“信息性”特征&#xff0c;这些特征在多变量时间序列分析…

【Java】了解线程 Thread 类的使用,如何创建、终止、等待一个线程,一文读懂不迷路

线程是什么 线程是操作系统中调度的基本单位&#xff0c;是比进程更小的执行单元。线程在进程内部运行&#xff0c;共享该进程的资源&#xff0c;如内存和文件句柄&#xff0c;但每个线程都有自己的执行栈和程序计数器。 线程的主要特点包括&#xff1a; 轻量级&#xff1a;…

格式工厂怎么转换mp4?简单4步实现视频转换

视频转换的重要性不言而喻。随着科技的发展&#xff0c;视频已经成为我们生活中不可或缺的一部分。然而&#xff0c;不同的设备和平台往往支持不同的视频格式&#xff0c;这就导致了视频兼容性问题。此外&#xff0c;不同格式的视频文件在存储和传输方面也存在差异。因此&#…

【MySQL】数据库基础与MySQL的安装

1. 数据库基础 1.1 什么是数据库 在接触数据库之前&#xff0c;回想一下我们之前写的所有小项目&#xff0c;如果需要持久化保存一些内容&#xff0c;我们是保存在文件中的&#xff0c;似乎也能够很不错的支持我们的操作&#xff0c;解决我们的需求。但是&#xff0c;实际上是…

健身房管理系统的设计与实现设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图详细视频演示技术栈系统测试为什么选择我官方认证玩家&#xff0c;服务很多代码文档&#xff0c;百分百好评&#xff0c;战绩可查&#xff01;&#xff01;入职于互联网大厂&#xff0c;可以交流&#xff0c;共同进步。有保障的售后 代码参考数据库参…