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.mzph.cn/news/696656.shtml

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

相关文章

C语言运用中断子系统用驱动控制led实验,c语言串口led点灯实验(驱动+应用层)

中断子系统用驱动控制led实验 驱动代码 #include <linux/init.h> #include <linux/module.h>#include<linux/interrupt.h> #include<linux/gpio.h> #include<linux/timer.h>#include<linux/of.h> #include<linux/of_irq.h> #inclu…

实现律所高质量发展-Alpha法律智能操作系统

律师行业本质上属于服务行业&#xff0c;而律师团队作为一个独立的服务单位&#xff0c;应当包含研发、市场、销售、服务等单位发展的基础工作环节。但现实中&#xff0c;很多律师团队其实并没有区分这些工作。鉴于此&#xff0c;上海市锦天城律师事务所医药大健康行业资本市场…

【SQL注入】靶场SQLI DUMB SERIES-26空格和注释被过滤

26题提示所有的空格和注释都会被过滤掉 输入?id0判断闭合方式&#xff0c;回显报错可以确定闭合方式为单引号 正常思路是需要通过注释符将后面的语句注释掉&#xff0c;但是这一关的注释符被过滤了&#xff0c;可以考虑使用将后面的语句也闭合的思路来避免引号带来的报错。输…

【leetcode】记忆化搜索

记忆化搜索 一、斐波那契数1、题目描述2、代码3、解析 二、不同路径1、题目描述2、代码3、解析 三、最长递增子序列1、题目描述2、代码3、解析 四、猜数字大小II1、题目描述2、代码3、解析 五、矩阵中的最长递增路径1、题目描述2、代码3、解析 一、斐波那契数 1、题目描述 le…

【java】小学生数学练习题目生成系统

本文章主要是CSDN-问答板块&#xff0c;有题主提出的问题&#xff0c;我这边将完整代码提供出来&#xff0c;仅供大家参考学习&#xff01; 一、效果截图 二、直接上代码 package com.example.dingtalk.question;import javax.script.ScriptEngine; import javax.script.Scrip…

PHP实践:Laravel中事件使用讲解

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

kafka生产者

1.原理 2.普通异步发送 引入pom&#xff1a; <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>3.0.0</version></dependency><dependency><g…

2024022202-查询优化

查询优化 概述 关系系统和关系模型是两个密切相关而有不同的概念。支持关系模型的数据库管理系统称为关系系统。但是关系模型中并非每一部分都是同等重要的&#xff0c;所以我们不苛求完全支持关系模型的系统才能称为关系系统。因此&#xff0c;我们给出一个关系系统的最小要求…

【学习总结】慢SQL治理经验总结

一、慢SQL定义 执行超过1s的SQL为慢SQL 三、慢SQl的风险 系统的响应时间延迟&#xff0c;影响用户体验 资源占用增加&#xff0c;增高了系统的负载&#xff0c;其他请求响应时间也可能会收到影响。 慢SQL占用数据库连接的时间长,如果有大量慢SQL查询同时执行&#xff0c;可能…

C语言中的assert.h:调试助手与断言详解

在C语言编程中&#xff0c;assert.h头文件提供了非常有用的断言&#xff08;Assertion&#xff09;功能&#xff0c;它主要用于开发和调试阶段&#xff0c;确保程序在运行时满足某些预期条件。如果这些条件未得到满足&#xff0c;则程序会立即停止执行&#xff0c;并打印出有关…

冷链物流追踪:Java与MySQL的协同实践

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

第三百六十一回

文章目录 1. 概念介绍2. 实现方法2.1 环绕效果2.2 立体效果 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义SlideImageSwitch组件"相关的内容&#xff0c;本章回中将介绍两种阴影效果.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本…

谷歌seo推广怎么做?

除了常规的优化之外&#xff0c;还可以针对特定垂直搜索进行优化&#xff0c;比如图片的以及视频的搜索优化&#xff0c;这对于贩卖自己产品的网站来说也是挺重要的一点 图片需要确保您的图片文件名包含相关关键词&#xff0c;并为每张图片添加描述性的ALT文本&#xff0c;以帮…

调用 Python 函数遗漏括号 ( )

调用 Python 函数遗漏括号 1. Example - error2. Example - correctionReferences 1. Example - error name "Forever Strong" print(name.upper()) print(name.lower)FOREVER STRONG <built-in method lower of str object at 0x0000000002310670>---------…

SqlServer2016离线安装--Microsoft R Open 和 Microsoft R Server安装文件位置

问题 SQL SERVE 2016离线安装&#xff0c;会出现“Microsoft R Open 和 Microsoft R Server 脱机安装”的界面&#xff0c; 无法点击下一步的情况&#xff0c;如下图&#xff1a; 原因 离线安装时需要下载两个文件 解决方案 1、访问路径下载文件 https://go.microsoft.c…

Python 实现 OBV 指标计算:股票技术分析的利器系列(7)

Python 实现 OBV 指标计算&#xff1a;股票技术分析的利器系列&#xff08;7&#xff09; 介绍算法解释 代码rolling函数介绍核心代码计算 VA 列计算 OBV 列计算 MAOBV 完整代码 介绍 OBV 指标是“On-Balance Volume”的缩写&#xff0c;意为“量价平衡指标”。它是一种用于衡…

《游戏引擎架构》 -- 学习4

资源及文件系统 文件系统 游戏引擎的文件系统API通常提供以下功能&#xff1a; 搜需路径&#xff1a;是含一串路径的字符串&#xff0c;各路径之间以特殊字符&#xff08;如冒号或分号&#xff09;分隔&#xff0c;找文件时就会从这些路径进行搜寻。例如在命令行下执行程序&a…

Code Composer Studio (CCS) - 全局搜索功能

Code Composer Studio [CCS] - 全局搜索功能 1. Ctrl H&#xff0c;全局搜索功能References 1. Ctrl H&#xff0c;全局搜索功能 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

【AI大模型】ChatGPT在地学、GIS、气象、农业、生态、环境等领域中的高级应用

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…

2024牛客(4)K题

登录—专业IT笔试面试备考平台_牛客网 using i64 long long; using ll long long; constexpr ll M 1e9 7; template<class Info> struct SegmentTree {int n;std::vector<Info> info;SegmentTree() : n(0) {}SegmentTree(int n_, Info v_ Info()) {init(n_, …