Lua内存管理策略

news2024/11/25 2:36:31

传统的内存管理策略主要分为两种:引用计数,和垃圾回收。相比后者每一段时间执行一次回收周期,前者是对于每一个变量都维护被引用数的策略。对于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 = nil

print(cacheTable[1]) --table: 000001F3334CAD40
collectgarbage() --zhangsan
print(cacheTable[1]) --nil
collectgarbage() --lisi

Weak表

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

collectgarbage函数

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

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

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

相关文章

自动化测试-RIDE编写自动化脚本

自动化脚本软件测试的必修内容,是自动化测试的核心,脚本的逻辑严谨性、可维护性非常重要,优秀的自动化脚本需要能兼顾用例的正确有效性和自动化测试的效率,本篇文章将介绍如何用RIDE写自动化脚本。我们将深入探讨RIDE的具体用法&a…

websocket数据帧格式

客户端、服务端数据的交换,离不开数据帧格式的定义。因此,在实际讲解数据交换之前,我们先来看下WebSocket的数据帧格式。 WebSocket客户端、服务端通信的最小单位是帧(frame),由1个或多个帧组成一条完整的消…

【Node.js】path 模块进行路径处理

Node.js 执行 JS 代码时,代码中的路径都是以终端所在文件夹出发查找相对路径,而不是以我们认为的从代码本身出发,会遇到问题,所以在 Node.js 要执行的代码中,访问其他文件,建议使用绝对路径 实例&#xff1…

比特币 P2PKH、P2SH

标准脚本P2PKH、P2SH 区块链重要基础知识7-1——标准脚本P2PKH、P2SH-CSDN博客 比特币中P2SH(pay-to-script-hash)多重签名的锁定脚本和解锁脚本 https://www.cnblogs.com/itlgl/p/10419325.html

如何设置HTML页面文字格式?

如何设置HTML页面文字格式? HTML 里的文本元素真的好有趣,它们能让文字呈现出不同的样式和含义。我决定深入探索一下,看看这些元素到底有哪些魔法。 HTML 文本格式化初探 在 HTML 里,想要改变文本的样式,就得靠那些…

【机器学习笔记】 9 集成学习

集成学习方法概述 Bagging 从训练集中进行子抽样组成每个基模型所需要的子训练集,对所有基模型预测的结果进行综合产生最终的预测结果: 假设一个班级每个人的成绩都不太好,每个人单独做的考卷分数都不高,但每个人都把自己会做的…

JDK8新增的时间

设计更合理,功能更丰富,使用更方便,都是不可变的对象,修改后会返回新的事件对象不会丢失最开始的时间,线程安全,能精确到毫秒、纳秒。 这三个类都有一个静态方法now():获取系统当前时间对应的该…

爬虫-华为云空间备忘录导出到docx-selenium控制浏览器行为-python数据处理

背景适用情况介绍 老的荣耀手机属于华为云系统,家里人换了新荣耀手机属于荣耀云系统无法通过云空间将备忘录转移到新手机,不想让他们一个一个搞,于是整了一晚上想办法爬取下来。从网页抓取下来,然后存到docx文档中(包…

不花一分钱,在 Mac 上跑 Windows(M1/M2 版)

这是在 MacOS M1 上体验最新 Windows11 的效果: VMware Fusion,可以运行 Windows、Linux 系统,个人使用 licence 免费 安装流程见 👉 https://zhuanlan.zhihu.com/p/452412091 从申请 Fusion licence 到下载镜像,再到…

phpstrom创建thinkphp项目

安装php和composer 参考 安装phpstrom 创建项目 查看thinkphp版本 https://packagist.org/packages/topthink/think 打开所在项目编辑配置 即可调试运行

软件工程师,超过35岁怎么办

概述 随着科技行业的飞速发展,软件开发工程师的职业道路充满了各种机遇和挑战。对于已经在这个行业摸爬滚打了十多年的软件开发工程师来说,当他们步入35岁这个年纪时,可能会感到一些迷茫和焦虑。许多人担忧,在以创新、活力、快速迭…

MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(2)-Swagger框架集成

Swagger是什么? Swagger是一个规范且完整API文档管理框架,可以用于生成、描述和调用可视化的RESTful风格的 Web 服务。Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就…

MySQL篇之覆盖索引

一、定义 覆盖索引是指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到。 二、例子 1. id为主键,默认是主键索引。 2. name字段为普通索引。 select * from tb_user where id 1 覆盖索引 select id,na…

Codeforces Round 486 (Div. 3)

目录 A. Diverse Team B. Substrings Sort C. Equal Sums D. Points and Powers of Two E. Divisibility by 25 F. Rain and Umbrellas A. Diverse Team 找出不重复的同时存下下标即可,依次遍历map判断重复最后判断数量即可 void solve(){cin>>n>>…

太炸了!Sora深夜发布!网友:我要失业了

2022年末,OpenAI聊天机器人ChatGPT的面世无疑成为了引领人工智能浪潮的标志性事件,宣告了新一轮科技革命的到来。无论是聊天娱乐、教育学习,还是工作生产、医疗健康等领域,人工智能正以前所未有的速度渗透到我们生活的方方面面。 …

ClickHouse--10--临时表、视图、向表中导入导出数据

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1.临时表1.1 特征1.2 创建一个临时表 2.视图2.1 普通视图2.2 物化视图 3.向表中导入导出数据3.1 案例 1.临时表 1.1 特征 ClickHouse 支持临时表,临时表…

【网站项目】154智能无人仓库管理

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

【图论】2-SAT

参考资料:2-SAT学习笔记 什么是2-SAT问题呢? (a∨b∨c)∧(a∨b∨c)∧(a∨b∨c),给出一个类似于这样的式子,让你找出满足条件的一个解,这样的问题就是SAT问题,因为每一个括号内都有三个被限制的变量&#…

人工智能学习与实训笔记(七):神经网络之模型压缩与知识蒸馏

人工智能学习笔记汇总链接:人工智能学习与实训笔记汇总-CSDN博客 本篇目录 七、模型压缩与知识蒸馏 7.1 模型压缩 7.2 知识蒸馏 7.2.1 知识蒸馏的原理 7.2.2 知识蒸馏的种类 7.2.3 知识蒸馏的作用 七、模型压缩与知识蒸馏 出于对响应速度,存储大…

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

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