当前位置: 首页 > news >正文

lua的GC

关于lua的gc云风大佬在 Lua GC 的源码剖析 系列文章中讲得很清楚,这里做一下简单的记录。

分步gc

lua使用的是一种三色标记清除算法(tri-color incremental mark & sweep),大体步骤如下:
初始阶段,所有对象标为白色;
标记阶段的开始,将所有从root可达的对象标记为灰色;
标记阶段,逐个取出灰色对象,将其本身标记为黑色,将其所有引用的白色对象标记为灰色;
当不存在灰色对象时,进入清除阶段,清除所有白色对象,将所有黑色对象标记回白色。

具体而言,lua的gc分为markroot、mark、atomic、sweepstring、sweep、finalize几个阶段(见singlestep())。
markroot函数将若干lua对象链表的根节点置为灰色,放入gray链表/队列;mark阶段类似树的广度优先遍历,从gray队列中取出灰色对象,标为黑色,再将其所引用的对象置为灰色,加入gray队列;mark是分步执行的,中间对象关系可能又发生变化,在开始清理工作前,还需要做最后一次扫描,这个过程不可以再被打断,就是atomic函数;sweepstring阶段分步清理字符串;sweep阶段分步清理其他对象;userdata对象可能会有自定义gc方法,finalize阶段就用来调用这些gc方法,userdata对象本身则放在下轮gc清理。

标记阶段和清除阶段都是可以分步的,所以称为分步gc。但中间可能出现这样的情况:A引用B,B引用C;A已经标记为黑色,B标记为灰色,C为白色;在gc间歇期间,程序修改了对象间的引用关系, B不再引用C,而A开始引用C。C本来是活跃对象,但却会被清除,这会造成严重错误。算法引入写屏障技术,来解决这种问题:将此 白色 对象标记成 灰色,称为barrier forward,因为正常是白色->灰色->黑色的转换方向;将此 黑色 对象标记回 灰色,称为barrier back。

如何确定gc的步伐大小是一系列的微操,见singlestep()、luaC_setp()。

数据类型

在Lua中共有9种数据类型,分别为nil、boolean、lightuserdata、number、string、table、function、userdata和thread。其中只有string table function thread四种在vm中以引用方式共享,是需要被GC管理回收的对象。其它类型都以值形式存在。
另外还有两种类型的对象需要被GC管理,分别是proto和upvalue。

string创建后挂载于g->strt->hash
upvalue创建后被链在g->uvhead
table、thread、function、proto则都是挂在g->rootgc上,在mark阶段简单加到gray队列即可

markroot

有3个链表用于标记和清理过程,gray是灰色对象的链表,grayagain是在atomic阶段需要再次标记的对象的链表,weak是弱表的链表。
markroot()先将这三个链表清空,再将mainthread、mainthread的全局表、注册表、各类型元表标记,放到gray队列中,开始mark阶段。

string

mark的时候只是置灰,不挂载到gray上,所以它没有黑色。
在sweepstring阶段集中处理g->strt->hash。

userdata

rootgc初始化为mainthread,创建其他对象时使用的是头部插入,所以mainthread是链表的最后一个元素。
但是luaS_newudata()中将userdata挂到mainthread后,所以rootgc链表被mainthread分为两部分,后边是userdata,前边是其他对象。
userdata没有灰色,mark时直接标为黑色。
atomic中遍历mainthread之后的userdata链表(luaC_separateudata()),空闲且有gc方法的从rootgc移到g->tmudata中。
finalize阶段专门用来处理tmudata链表,对每个元素标记为白色,返还给rootgc,然后调用它的gc方法。
没有gc方法的空闲数据,就在sweep阶段被清理掉;有gc方法的,第一轮gc时先调用gc方法,第二轮gc时在sweep阶段清理掉userdata本身,通过finalized标志来识别userdata的状态。

string和userdata不引用其他对象,都是叶子节点。

upval

mark的时候:
如果是opend的,其指向栈上变量,将其指向的变量变灰;
如果是closed,其已是叶子节点,直接变黑。

以下引用自 Lua GC 的源码剖析 (4):

为何 open 状态的 TUPVAL 需要留为灰色待处理呢?这是因为 open TUPVAL 是易变的。GC 分步执行,我们无法预料在 mark 流程走完前,堆栈上被引用的数据会不会发生变化。事实上,在 mark 的最后一个步骤,我们会看到所有的 open TUPVAL 被再次 mark 一次,做这件事情的函数是 remarkupvals。

thread

mark的时候,从gray移到grayagain,且不变黑。
堆栈是随着运行过程不断变化的,为了效率其上数据的修改是不经过barrier的,所以把它推迟到atomic阶段重扫描。

table

traversetable()的时候,弱表不会从灰变黑,而是转移到weak链表上。
若弱表引用的元素被移除,也需要将元素从弱表中移除,atomic()中会调用cleartable()来做这件事。
移除table中hash部分value为nil的entry是通过removeentry():

static void removeentry (Node *n) {lua_assert(ttisnil(gval(n)));if (iscollectable(gkey(n)))ttype(gkey(n)) = LUA_TDEADKEY; /* dead key; remove it */
}

可以看到只是将key设为LUA_TDEADKEY类型,并没有从表中真删掉,那何时真正删除呢?是rehash的时候。
所以 高性能 Lua 技巧(译) 中这样说“你不该期望通过从一个大表里删除一些数据来回收内存,更好的做法是删除这个表本身。”。

参考

讲解 Lua 内部实现的 gc 机制
Lua GC 的工作原理
Lua GC 的源码剖析

相关文章:

lua的GC

关于lua的gc云风大佬在 Lua GC 的源码剖析 系列文章中讲得很清楚,这里做一下简单的记录。 分步gc lua使用的是一种三色标记清除算法(tri-color incremental mark & sweep),大体步骤如下: 初始阶段,所…...

基于python爬虫对豆瓣影评分析系统的设计与实现

基于python爬虫对豆瓣影评分析系统的设计与实现 Design and Implementation of a Python-based Web Crawler for Analyzing Douban Movie Reviews 完整下载链接:基于python爬虫对豆瓣影评分析系统的设计与实现 文章目录 基于python爬虫对豆瓣影评分析系统的设计与实现摘要第一…...

想让梦想照进现实?六西格玛绿带培训为你架起桥梁

六西格玛,这个源自摩托罗拉的质量管理方法论,如今已成为全球众多企业追求卓越的秘诀。它强调以数据为基础,通过减少变异和浪费,提高流程效率和质量,进而提升企业整体绩效。而六西格玛绿带培训,则是这个强大…...

大数据面试题之HDFS

目录 HDFS文件写入和读取流程 HDFS组成架构 介绍下HDFS,说下HDFS优缺点,以及使用场景 HDFS作用 HDFS的容错机制 HDFS的存储机制 HDFS的副本机制 HDFS的常见数据格式,列式存储格式和行存储格式异同点,列式存储优点有哪些? …...

(9)农作物喷雾器

文章目录 前言 1 必要的硬件 2 启用喷雾器 3 配置水泵 4 参数说明 前言 Copter 包括对农作物喷雾器的支持。该功能允许自动驾驶仪连接到一个 PWM 操作的泵和(可选)旋转器,根据飞行器速度控制液体肥料的流动速度。 稍微过时的视频显示了…...

智慧互联:Vatee万腾平台展现科技魅力

随着科技的迅猛发展,我们的生活正逐渐变得智能化、互联化。在这个信息爆炸的时代,一个名为Vatee万腾的平台正以其独特的魅力,引领我们走向一个更加智能的未来。 Vatee万腾,这个名字本身就充满了对科技未来的憧憬与期待。作为一家专…...

Charles抓包工具系列文章(四)-- Rewrite 重写工具

一、背景 这是一款比Map Local/Remote 还强大的工具,更加灵活,体现在以下几点: 重写request报文重写response报文header 字段的增删改query param 字段的增删改重写 body 字段改写http 响应状态status重写host/url/path 从这也可以看出其强…...

【PB案例学习笔记】-24创建一个窗口图形菜单

写在前面 这是PB案例学习笔记系列文章的第24篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上传到了gite…...

环境配置的相关问题

一、shap安装踩坑 遇到错误: A module that was compiled using NumPy 1.x cannot be run in NumPy 2.0.0 as it may crash. To support both 1.x and 2.x versions of NumPy, modules must be compiled with NumPy 2.0. Some module may need to rebuild instead…...

github配置可拉取项目到本地

首先配置用户名和邮箱: git config --global user.name 自己的名字git config --global user.email 自己的邮箱配置完之后检查一下: git config --global user.namegit config --global user.email如果提示的是自己配置好的名字和邮箱就Ok 然后拉取githu…...

Snippet-AndroidFontWeight

常用FontWeight值 <?xml version"1.0" encoding"utf-8"?> <resources><integer name"font_weight_Thin">100</integer><integer name"font_weight_ExtraLight">200</integer><integer name…...

选择合适的分类评价指标:传统指标与自定义指标的权衡

这里写目录标题 选择合适的分类评价指标&#xff1a;传统指标与自定义指标的权衡传统评价指标**准确率&#xff08;Accuracy&#xff09;****精确度&#xff08;Precision&#xff09;和召回率&#xff08;Recall&#xff09;****F1分数&#xff08;F1 Score&#xff09;** 自定…...

数据结构-线性表的链式表示

目录 前言一、线性表的链式表示和实现1.1 线性表的表示1.2 基本操作的实现1.3 线性表的链式表示的优缺点 总结 前言 本篇文章主要介绍线性表的链式表示 一、线性表的链式表示和实现 1.1 线性表的表示 线性表的链式表示又称为链式存储结构或链式映像 链式存储定义&#xff1…...

DDL-表操作-数据类型

一.DDL-表操作-数据类型 MySQL中的数据类型有很多,主要分为三类:数值类型,字符串类型,日期类型。 二.关系表 注意: 无符号和有符号的取值范围不是一样的,无符号需要加上UNSIGNED范围。 BLOB&#xff1a;用来描述二进制数据 TEXT:用来描述字符串 三.定长字符串和变长字符串 c…...

python实例代码 - 多层感知机预测销售情况

多层感知器预测销售情况 将一种广告投放到TV、newspaper、radio上时不同组合的情况会对应不同的销售量。 # -*- coding:utf-8 -*- # PredicateAdvertise.py # 多层感知器预测销售情况 # 将一种广告投放到TV、newspaper、radio上时不同组合的情况会对应不同的销售量。 import …...

JVM专题十:JVM中的垃圾回收机制

在JVM专题九&#xff1a;JVM分代知识点梳理中&#xff0c;我们主要介绍了JVM为什么采用分代算法&#xff0c;以及相关的概念&#xff0c;本篇我们将详细拆分各个算法。 垃圾回收的概念 垃圾回收&#xff08;Garbage Collection&#xff0c;GC&#xff09;确实是计算机编程中的…...

MySQL入门学习-索引.创建索引

索引是 MySQL 中用于加速查询的一种数据结构。它通过在表的列上创建索引来加快数据的检索速度。 一、索引的概念 索引类似于书的目录&#xff0c;可以快速定位到表中的数据。当在表中的列上创建索引后&#xff0c;MySQL 会根据索引列的值对数据进行排序&#xff0c;并建立一个…...

ChatGPT智能对话绘画系统 带完整的安装源代码包以及搭建教程

系统概述 ChatGPT 智能对话绘画系统是一款集智能语言处理和绘画创作于一体的综合性系统。它利用了深度学习和自然语言处理技术&#xff0c;能够理解用户的意图和需求&#xff0c;并通过与用户的交互&#xff0c;生成富有创意的绘画作品。该系统的核心是一个强大的人工智能模型…...

巴中市红色旅游地管理系统

摘 要 随着红色旅游的兴起&#xff0c;越来越多的人开始对巴中市的红色旅游地产生兴趣。巴中市作为中国革命的重要发源地之一&#xff0c;具有丰富的红色旅游资源。然而&#xff0c;目前巴中市红色旅游地的管理仍然存在许多问题&#xff0c;如信息不对称、资源利用效率低等。为…...

ROS2从入门到精通2-2:详解机器人3D可视化工具Rviz2与案例分析

目录 0 专栏介绍1 什么是Rviz2&#xff1f;2 Rviz2基本界面3 Rviz2基本数据类型4 数据可视化案例4.1 实例1&#xff1a;显示USB摄像头数据4.2 实例2&#xff1a;显示球体 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底层基本分布式原理&#xff0c;并具有…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...

内窥镜检查中基于提示的息肉分割|文献速递-深度学习医疗AI最新文献

Title 题目 Prompt-based polyp segmentation during endoscopy 内窥镜检查中基于提示的息肉分割 01 文献速递介绍 以下是对这段英文内容的中文翻译&#xff1a; ### 胃肠道癌症的发病率呈上升趋势&#xff0c;且有年轻化倾向&#xff08;Bray等人&#xff0c;2018&#x…...