Lua内存管理策略

传统的内存管理策略主要分为两种:引用计数,和垃圾回收。相比后者每一段时间执行一次回收周期,前者是对于每一个变量都维护被引用数的策略。对于Lua这种轻量化语言而言,占据大内存的开销是极力避免的,而前者的方式显然是增加内存开销的坏主意。因此Lua采取了垃圾回收的机制,这也是本篇文章的主题。

垃圾收集原理

分为两个阶段:标记-清除阶段。

标记阶段

从根集(全局变量,当前访问的局部变量等等)开始,依次向内部递归标记活动对象。

清除阶段

扫描所有对象,没有被标记的对象都被认为是不再被引用的对象,可以释放内存。

垃圾收集策略

目前Lua有两种策略:增量式GC和分代式GC。Lua默认收集策略是前者。

增量式GC

此模式下,每个GC循环都会和主程序交错运行,并不会在一段时间内完成所有的GC步骤。在此模式下的总GC时间是不会变的,但是相比于之前那种完整的一段时间的卡顿,是要优化不少的。

引入三个参数:收集器频率、收集器步进乘数、收集器步进。

第一个参数意指内存使用量达到上次垃圾收集后的内存的n%时执行收集操作。默认为200,即达到上次收集的内存两倍时开始新循环,小于100意味着直接执行收集操作,最大为1000。

第二个参数意指标记/扫描元素的速度。默认值是100,最大值是1000。值越大标记速度越快,但需要的分配内存也会越大。

第三个参数意指执行标记步骤之前分配多少内存。此数字n指的是2^n字节。较大的值可能会使增量式GC转变成早前版本的非增量式GC。

使用的是三色标记法来实现增量式GC。

如图所示,分为三个色系。

黑色为被标记且已经被完全检查引用的对象。

灰色为被标记但是还没有被完全检查引用的对象。

白色是暂时还没有被标记的对象。

我们从根系开始寻找对象,直到不再有灰色对象存在为止(因为灰色对象最终都会转成黑色)。最终所有白色对象都应当被回收。

增量GC过程中或许会有新的引用关系,因此需要考虑以下两个问题:

1.已经被标为黑色的对象和白色的对象之间建立了新的联系怎么办

2.被标为灰色的对象和之前引用它的黑色对象之间断开联系了怎么办

对于第一个问题,可以通过增量更新的方式解决:插入引用关系的时候,将黑色对象记录下来,等到标记过程完全结束后,重新扫描这类黑色对象,那些被标记为白色的对象重新成为灰色对象并再次执行以上检查引用操作。

对于第二个问题,可以通过原始快照的方式解决,也和上面方法类似,记录下来变动的黑色对象,标记过程结束后重新扫描。当然也可以选择不理睬,因为这类灰色对象引用断开后会在下一次GC过程中成为白色对象,依然会被清除。

分代式GC

此模式下,收集器会频繁进行次要收集,仅遍历最近创建的对象;次要收集后仍高于内存限制,则进行主要收集,遍历所有对象。

引入两个参数:次要收集频率,主要收集频率。

这两个参数都意指在内存使用量超过上次收集后的内存的n%时(注意是超过,增量式GC的频率值是达到)实行收集策略。前者是超过n%时开始次要收集,默认值是20,最大值是200;后者是超过n%时开始主要收集,默认值是100,最大值是1000。

分为两种对象:新生代和老年代。其根据对象创建时机判断(即经历了多少次垃圾收集)。次要收集主要收集这些新生代,原因在于许多新创建的对象很快就不会再被需要了,而老年代通常会继续存活下来。

分代式GC的优点在于减少暂停时间,收集效率变高,但同时也因为其复杂性和优先级,会容易使老年代可能占据内存的较长时间。

辅助垃圾收集

有时候Lua并不清楚哪些是我们所认为的垃圾,所以需要我们自身做辅助工作保证Lua完成释放内存的任务。

析构器

一个对象被回收时,如果其有__gc元方法,则会调用此方法。注意,官方文档中强调,执行这段元方法时会短暂地复活这个对象,原因是元方法内部可能会有对象自身的调用。但是这是暂时的,如果此元方法没有改变对象的引用信息(比如这个对象被全局变量引用),那么下一次GC依然会把这个对象给收集掉。还有一点值得注意:如果gc内部又赋值了一次gc元方法,则会在下一次gc时又调用一次gc元方法,参考以下代码:

t = {name = "zhangsan"}
setmetatable(t,{__gc = function (t)print(t.name)t.name = "lisi"setmetatable(t,{__gc = function (t)print(t.name)end})
end})--用一个weak表管理
local cacheTable = {}
setmetatable(cacheTable,{__mode = 'v'
})
table.insert(cacheTable,t)t = nilprint(cacheTable[1]) --table: 000001F3334CAD40
collectgarbage() --zhangsan
print(cacheTable[1]) --nil
collectgarbage() --lisi

Weak表

参考之前的博客:Lua weak表-CSDN博客

collectgarbage函数

显式调用函数以使得Lua直接执行回收相关的操作。

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

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

相关文章

文件夹删不掉,显示在另一个文件中打开怎么办

问题: 一、想要删掉这个文件夹,却因为文件夹中的文件打开了删不掉,这里我因为做的测试,所以是知道打开了什么 二、一般情况下文件比较多时,是不知道打开了什么的,长这个样子 解决: 一、打开任…

《Go 简易速速上手小册》第4章:接口与抽象(2024 最新版)

文章目录 4.1 接口的定义与实现 - Go 语言的多面手4.1.1 基础知识讲解4.1.2 重点案例:动物乐队功能描述实现代码 4.1.3 拓展案例 1:通用支付系统拓展案例 1:通用支付系统功能描述实现代码 4.1.4 拓展案例 2:动物园管理器拓展案例 …

数学实验第三版(主编:李继成 赵小艳)课后练习答案(十一)(4)(5)

实验十一:非线性方程(组)求解 练习四 1.费根鲍姆(Feigenbaum)对超越函数 (λ为非负实数)进行了分叉与混沌的研究,试利用迭代格式 ,做出相应的费根鲍姆图. clc;clear; a0.5;%x初值取0.5 for l1:0.01:1.5hold on x[a]; for k2:150x(k)l*sin…

通过玩游戏学会AWS

游戏名字: Cloud Quest 类型:亚马逊云科技官方出了一款 3D 角色扮演、虚拟城市建造形式的游戏实验课 进入方法:浏览器搜索 Cloud Quest(或扫描下方二维码)进入 Cloud Quest 课程页。 选择以下的链接 点击进行注册 进…

GPT-4带来的思想火花

GPT-4能够以其强大的生成能力和广泛的知识储备激发出众多思想火花。它能够在不同的情境下生成新颖的观点、独特的见解和富有创意的解决方案,这不仅有助于用户突破思维定势,还能促进知识与信息在不同领域的交叉融合。 1.GPT-4出色的创新思考和知识整合能…

MIT-BEVFusion系列八--onnx导出2 spconv network网络导出

这里写目录标题 export-scn.py加载模型设置每层的精度属性初始化输入参数导出模型model.encoder_layers 设置初始化参数设置 indice_key 属性更改 lidar backbone 的 forward更改lidar网络内各个层的forward带参数装饰器,钩子函数代码使用装饰器修改forward举例 跟踪…

Ubuntu Desktop 显示文件路径

Ubuntu Desktop 显示文件路径 1. GUI hot key2. CLIReferences 1. GUI hot key Ctrl L: 显示文件路径 2. CLI right click -> Open in Terminal -> pwd strongforeverstrong:~/Desktop$ pwd /home/strong/DesktopReferences [1] Yongqiang Cheng, https://yongqiang…

51单片机项目(31)——基于51单片机篮球计分器的proteus仿真

1.功能设计 可以通过两组按键,控制两个队伍的加减分,加分设置有+1分按键,+2分按键,+3分按键。减分设置有-1分按键。 设置有开始/暂停按键,按下开始,数码管便开…

【读书笔记】ICS设备及应用攻击(一)

工控系统通常是由互联设备所构成的大型复杂系统,这些设备包括类似于人机界面(HMI)、PLC、传感器、执行器以及其他使用协商好的协议进行相互通信的设备。所有交互背后的驱动力都是软件,软件为工控系统中几乎所有部分的运行提供支撑…

云计算基础-存储基础

存储概念 什么是存储: 存储就是根据不同的应用程序环境,通过采取合理、安全、有效的方式将数据保存到某些介质上,并能保证有效的访问,存储的本质是记录信息的载体。 存储的特性: 数据临时或长期驻留的物理介质需要保…

Ubuntu忘记登录密码重置步骤

Ubuntu忘记登录密码重置步骤 1.开机界面长按shitf键,进入grub,并选择Advanced options for ubuntu,按下回车 2.选择一个较新版本的recovery mode,按下回车 3.会跑一些数据,等待跑完后会出现下面的界面,选择…

算法刷题:无重复字符的最长字串

无重复字符的最长字串 .题目链接题目详情算法原理题目解析滑动窗口定义指针进窗口判断出窗口更新结果 我的答案 . 题目链接 无重复字符的最长字串 题目详情 算法原理 题目解析 首先,为了使字符串遍历的更加方便,我们选择将字符串转换为数组 题目要求子串中不能有重复的字符…