LuaJIT Garbage Collector Algorithms

Explain

本篇文章是对Make Pall发表wili内容《LuaJIT 3.0 new Garbage Collector》的翻译和扩展,因为原文是对LuaJIT 2.x GC重要功能的简介和对LuaJIT 3.0 new GC的工作计划,所以它并不是系统性介绍GC的文章。希望以后能有精力系统性的对LuaJIT 2.x GC做个总结。

到目前(2025-1-17)为止,LuaJIT 3.0尚未发布。看Make列的3.0 plan,其中优化了很多功能,非常值得期待。但他也说了,3.0有可能永远不会发布,这将是非常遗憾的一件事情。

一、Two-Color Mark & Sweep

Two-Color Mark & Sweep 是标记-清除算法的简化版本,使用两种颜色(白色和黑色)来表示对象的状态:

  • 白色对象:表示未被访问的对象,默认情况下所有新分配的对象都是白色。如果一个对象在垃圾回收周期中结束时仍然是白色,说明它是不可达的,可以被回收。
  • 黑色对象:表示已被标记为可达的对象。黑色对象不会被清除,并会在清除阶段颜色翻转为白色以便参与下一个 GC 周期。

1.1 GC流程

标记阶段(Mark Phase)从 GC 根(例如,主线程,全局变量等)开始,迭代遍历所有可达(live)对象,并将它们标记为黑色。待标记完成,没有被标记为黑色的对象都被视为无法访问,即死对象。

清除阶段(Sweep Phase)遍历所有内存中的对象:如果对象为白色,则认为其是死对象,将其释放;如果对象为黑色,则认为其可达,将颜色翻转为白色,准备参与下一次GC。

在这里插入图片描述

1.2 主要缺点

该算法的主要缺点是非增量式(non-incremental),整个垃圾回收过程必须一次性完成,程序代码(mutator,指运行中的程序)无法与垃圾回收器并行执行。即回收操作是原子性的,需要完全暂停程序运行,这种暂停称为 Stop-the-world(STW),会导致程序响应延迟,特别是当内存中有大量对象时,暂停时间可能很长。

这种回收方式不适合实时系统或对响应时间要求高的场景,例如游戏或用户界面。

1.3 优化思路

为了提升效率和降低开销,算法中可以引入一些优化,例如:

  • 交换颜色的意义:在每次垃圾回收结束后,反转白色和黑色的定义。例如,将“黑色”定义为“未访问”,将“白色”定义为“可达”。这样可以避免在清除阶段对黑色对象的颜色翻转操作,减少额外的步骤。
  • 增量式改进:尽管基础算法是非增量式的,但可以通过引入写屏障(Write Barrier)等机制改进为增量式标记。

1.4 应用实例

Lua 5.0 使用了 Two-Color Mark & Sweep 算法,具有以下特点:

  • 对象存储结构:所有对象都存储在一个链表中。这种设计的优点是方便遍历内存中的所有对象,缺点是访问速度较慢。
  • 标记列表(Mark List):在标记阶段,将需要遍历的对象放入一个独立的标记列表。这样可以加速标记阶段中对对象的处理,同时避免重复标记。
  • 内存回收效率:Lua 5.0 的 GC 虽然简单,但由于设计目标是轻量级脚本语言,这种算法在小型脚本的场景中表现较好。

二、Tri-Color Incremental Mark & Sweep

Two-Color Mark & Sweep是 全停顿(Stop-the-world,STW) 的算法,会导致程序在垃圾回收时暂停。为了减少暂停时间,增量式垃圾回收 (Incremental GC)被提出, Tri-Color Marking则是其一种常用的技术。

Tri-Color Incremental是 Lua 5.1/5.2 和 LuaJIT 1.x/2.x 使用的 GC 算法,它是 Lua 5.0 链表算法的增强版。

Tri-Color Incremental Mark & Sweep 用三种颜色(白色、灰色、黑色)来区分对象的状态,三种颜色的定义如下:

  • 白色(White):表示未访问的对象。在标记阶段开始时,所有的对象都被标记为白色。如果某个对象在整个标记阶段结束后仍然是白色,则说明该对象是不可达的垃圾,可以被回收。
  • 灰色(Gray):表示已被标记,但未处理其引用对象的对象。意味着当前对象是可达的,但它可能引用其他未处理的对象。
  • 黑色(Black):表示已被标记并且其引用对象也被处理完毕的对象。意味着该对象和它的引用对象都是可达的,无需再次处理。

2.1 GC流程

任何时刻新分配的对象都被标记为白色。

标记阶段,垃圾回收器从GC根(GCroots)开始,遇到一个可达的对象,将其颜色从白色变为灰色,并将其加入灰色栈(graystack,或重新链入灰色列表)。灰色栈中的对象会被逐一迭代处理,每次从栈中移除一个灰色对象,遍历灰色对象的所有引用,将其引用的对象标记为灰色,并将灰色对象加入灰色栈中。一个对象的所有引用遍历完成后,将其颜色会灰色变为黑色。

清除阶段与前面提到的Two-Color算法类似。遍历所有内存中的对象:如果对象为白色,则认为其是死对象,将其释放;如果对象为黑色,则认为其可达,将颜色翻转为白色,准备参与下一次GC。

在这里插入图片描述

2.2 增量式(Incremental)

为了避免一次性完成垃圾回收而导致程序长时间暂停,Tri-Color 标记算法可以增量执行。垃圾回收器采用分段标记,一次只处理少量灰色对象,然后将控制权交还给应用程序(mutator)。

这种方式将垃圾回收暂停分散为许多短间隔,特别适合对交互性要求高的场景(例如游戏或互联网服务器)。

增量式GC存在黑色对象引用白色对象的问题。在增量过程中,mutator可能在回收器工作时,创建一个新的标记为白色的对象,并将白色对象(未处理)存储到一个黑色对象(已处理)中。如果发生这种情况,这个白色对象不会被标记为可达对象,而是在清除阶段被错误地回收,即使它实际上可以从一个可达对象中访问到。

对于此问题的解决方法,是维护三色不变性(Tri-ColorInvariant),GC必须满足以下两个不变性之一:

  1. 强三色不变性(Strong Tri-Color Invariant):黑色对象不能直接引用白色对象。如果存在这种情况,白色对象可能会被错误地认为是不可达的,从而被误回收。
  2. 弱三色不变性(Weak Tri-Color Invariant):黑色对象可以直接引用白色对象,但要求该白色对象必须存在其他灰色对象对它的引用,或者它的可达链路上游存在灰色对象。

通过插入屏障(Insertion Barrier)机制来实现。当对象A引用对象B时,如果对象B是白色,则将其标记为灰色,从而避免黑色对象直接引用白色对象。

2.3 写屏障(Write Barrier)

如果mutator在增量执行中破坏了三色不变性(如添加了新的引用),需要通过写屏障(Write Barrier)来修复。

写屏障(Write Barrier)在每次写操作后检查是否违反了三色不变性,如果发现不变性被破坏,需要采取修复操作。有两种修复方式:

  • 后向屏障(Backward Barrier):将黑色对象重新变为灰色,并将其重新加入灰色栈中,以便稍后重新处理。优点:对于需频繁写入(例如容器对象)的对象,可以减少对相同对象的后续屏障检查。
  • 前向屏障(Forward Barrier):立即将白色对象标记为灰色,并将其加入灰色栈中。优点:可以推动垃圾回收向前运行,适用于只进行孤立写操作的对象。

Lua 5.1/5.2 和 LuaJIT 1.x/2.x对Tables使用后向屏障,所有其他可遍历对象使用前向屏障。

LuaJIT 2.x 通过只检查标记黑色的table(忽略存储对象的颜色)进一步优化了table的写屏障。这样检查速度更快,而且仍然安全:写屏障可能会更频繁地触发,但这没有坏处。而且这在实践中并不重要,因为 GC 周期进展非常快,中间有较长的暂停,所以对象很少是黑色的。而且,存储的对象通常都是白色的。


以下是Mike Pall对LuaJIT中写屏障的一些介绍:

写屏障只需检查存储到其中的对象的灰色位(gray bit)。这是一个非常快速的测试,并且只有在未设置灰色位时才会触发(这种情况很少见)。

如果触发了写屏障,白色对象将变为浅灰色(light-gray),黑色对象将变为深灰色(dark-gray),深灰色对象还会被推送到快速顺序存储缓冲区 (sequential store buffer,SSB) 上。

浅灰色对象不需要推送到 SSB,但这需要检查标记位。如果触发屏障的性能成为问题,则可以避免这种情况。可以改为对 SSB 溢出进行检查。当收集器暂停时,可以完全避免检查标记位,因为不可能有任何黑色对象。

2.4 重要优化

程序堆栈(Stacks)始终保持为灰色,并在清除阶段之前重新遍历。这样可以避免对堆栈插槽的写入使用写屏障(堆栈插槽是写入操作最频繁的地方)。

没有对子对象的引用的对象可以立即从白色变为黑色,而不需要经过灰色堆栈。

可以通过使用两个白色并在进入清除阶段之前在它们之间翻转来使清除阶段成为增量。需要保留具有“current”白色的对象。只有具有“other”白色的对象才应该被释放。

三、Quad-Color Optimized Incremental Mark & Sweep

在这里插入图片描述

四、Generational GC

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

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

相关文章

ChatGPT大模型极简应用开发-CH1-初识 GPT-4 和 ChatGPT

文章目录 1.1 LLM 概述1.1.1 语言模型和NLP基础1.1.2 Transformer及在LLM中的作用1.1.3 解密 GPT 模型的标记化和预测步骤 1.2 GPT 模型简史:从 GPT-1 到 GPT-41.2.1 GPT11.2.2 GPT21.2.3 GPT-31.2.4 从 GPT-3 到 InstructGPT1.2.5 GPT-3.5、Codex 和 ChatGPT1.2.6 …

基于单片机的直流电机控制系统(论文+源码)

1 系统方案设计 本设计基于单片机的直流电机控制系统的总体架构设计如图2.1所示,其采用STM32F103单片机作为控制器,结合ESP8266 WiFi通信模块、L9110电机驱动电路、OLED液晶、按键等构成整个系统。用户在使用时,可以通过按键或者手机APP设定直…

【Linux】Linux入门(2)常见指令

目录 Linux下的文件ls 指令 --- 展示目录pwd指令 --- 显示当前目录cd 指令 --- 改变工作目录touch指令 --- 创建普通文件stat指令 --- 查看文件属性mkdir指令 --- 创建目录rmdir指令 --- 删除目录rm指令 --- 同时删除文件或目录man指令 --- 访问帮助手册cp指令 复制文件或目录m…

《自动驾驶与机器人中的SLAM技术》ch4:基于预积分和图优化的 GINS

前言:预积分图优化的结构 1 预积分的图优化顶点 这里使用 《自动驾驶与机器人中的SLAM技术》ch4:预积分学 中提到的散装的形式来实现预积分的顶点部分,所以每个状态被分为位姿()、速度、陀螺零偏、加计零偏四种顶点&am…

BMC知识框图

OpenBMC简介 OpenBMC作为BMC的Linux发行版,旨在管理广泛系统,如企业、高性能计算、电信和大规模数据中心。 BMC,或Baseboard Manager Controller,是服务器主板上的专用微控制器,采用IPMI架构,具备智能性&…

书生大模型基础岛第五关

基础任务:使用 XTuner 微调 InternLM2-Chat-7B 实现自己的小助手认知,如下图所示(图中的尖米需替换成自己的昵称),记录复现过程并截图。 1.配置环境 2.修改数据,将尖米修改为人工智能小助手 修改之前 修改…

EI Scopus双检索 | 2025年第四届信息与通信工程国际会议(JCICE 2025)

会议简介 Brief Introduction 2025年第四届信息与通信工程国际会议(JCICE 2025) 会议时间:2025年7月25日-27日 召开地点:中国哈尔滨 大会官网:www.jcice.org 由黑龙江大学和成都信息工程大学主办,江苏科技大学协办的2025年第四届信…

于灵动的变量变幻间:函数与计算逻辑的浪漫交织(下)

大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。 这一节我们主要来学习单个函数的声明与定义,static和extern… 这里写目录标题 一、单个函数…

Python Pyside6 加Sqlite3 写一个 通用 进销存 系统 初型

图: 说明: 进销存管理系统说明文档 功能模块 1. 首页 显示关键业务数据商品总数供应商总数本月采购金额本月销售金额显示预警信息库存不足预警待付款采购单待收款销售单2. 商品管理 商品信息维护商品编码(唯一标识)商品名称规格型号单位分类进货价销售价库存数量预警…

2025西湖论剑-babytrace

前言 就做了下题目,pwn1/3 都是签到,pwn2 后面绕 ptrace 有点意思,简单记录一下 漏洞分析 子进程中的读/写功能没有检查负数的情况,存在越界读写: void __fastcall get_value(__int64 *int64_arr) {__int64 ll; //…

西门子【Library of Basic Controls (LBC)基本控制库”(LBC) 提供基本控制功能】

AF架构中使用的库 文章目录 Table of contents Legal information ..............................................................................................................................2 1 Introduction ................................................…

Phi小模型开发教程:用C#开发本地部署AI聊天工具,只需CPU,不需要GPU,3G内存就可以运行,不输GPT-3.5

大家好,我是编程乐趣。 行业诸多大佬一直在说:“‌2025年将是AI应用元年‌”,虽然说大佬的说法不一定对,但AI趋势肯定没错的。 对于我们程序员来说,储备AI应用开发技能,不管对找工作、接项目、创业肯定是…

python-leetcode-存在重复元素 II

219. 存在重复元素 II - 力扣(LeetCode) class Solution:def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:seen set()for i, num in enumerate(nums):if num in seen:return Trueseen.add(num)if len(seen) > k:seen.remove…

如何将本地 Node.js 服务部署到宝塔面板:完整的部署指南

文章简介: 将本地开发的 Node.js 项目部署到线上服务器是开发者常见的工作流程之一。在这篇文章中,我将详细介绍如何将本地的 Node.js 服务通过宝塔面板(BT 面板)上线。宝塔面板是一个强大的服务器管理工具,具有简洁的…

1月15学习

[SWPUCTF 2018]SimplePHP phar反序列化的三个前提条件 可以上传phar文件 有可以利用的魔术方法 文件操作函数的参数可控 网站中有两个功能:查看文件和上传文件,利用查看文件将源码都先弄下来进行PHP代码审计。 可以看到存在任意文件读取漏洞&#xff0…

【网络 MAC 学习专栏 -- 如何理解 PHY 的 Link Up】

请阅读【嵌入式开发学习必备专栏 Cache | MMU | AMBA BUS | CoreSight | Trace32 | CoreLink | ARM GCC | CSH】 文章目录 OverviewClause 22/Clause 45Clause 22Clause 45 PHY Link 状态的软件实现 转自: 开心果 Need Car 2022年10月20日 09:50 上海 Overview PHY…

慧集通(DataLinkX)iPaaS集成平台-系统管理之用户及权限

系统用户 通过左侧菜单栏【系统管理】→【用户及权限】→【系统用户】进入到系统用户维护的主界面,在该界面我们可以看到已经维护好的系统用户,以及一些关于系统用户的功能按钮,有新建、编辑、删除、停用、启用、解锁等。 新建:在…

【机器学习实战入门】基于深度学习的乳腺癌分类

什么是深度学习? 作为对机器学习的一种深入方法,深度学习受到了人类大脑和其生物神经网络的启发。它包括深层神经网络、递归神经网络、卷积神经网络和深度信念网络等架构,这些架构由多层组成,数据必须通过这些层才能最终产生输出。…

Spring Boot + Apache POI 实现 Excel 导出:BOM物料清单生成器(支持中文文件名、样式美化、数据合并)

目录 引言 Apache POI操作Excel的实用技巧 1.合并单元格操作 2.设置单元格样式 1. 创建样式对象 2. 设置边框 3. 设置底色 4. 设置对齐方式 5. 设置字体样式 6.设置自动换行 7. 应用样式到单元格 3. 定位和操作指定单元格 4.实现标签-值的形式 5.列宽设置 1. 设…

[每周一更]-(第132期):AI工具集对比

文章目录 1.问答互动类(31个)2.图像类**简要对比说明**: **总结**: 3.代码类WindsurfCursor AIGithub Copilot 4.大模型**AlphaFold 的独特性与优势****AlphaFold 的局限性****主要大模型对比** AI的核心目标是通过模拟人类智能来…