Lua学习笔记:浅谈对垃圾回收的理解

news2024/11/26 15:43:11
前言
本篇在讲什么

Lua的垃圾回收
本篇适合什么

适合初学Lua的小白
本篇需要什么

Lua语法有简单认知
依赖Sublime Text编辑器

本篇的特色

具有全流程的图文教学
重实践,轻理论,快速上手
提供全流程的源码内容


★提高阅读体验★

👉 ♠ 一级标题 👈

👉 ♥ 二级标题 👈

👉 ♣ 三级标题 👈

👉 ♦ 四级标题 👈


目录

  • ♠ 概述
  • ♠ 弱引用表
    • ♥ 示例
      • ♣ 弱引用键
      • ♣ 弱引用值
    • 在这里插入图片描述
  • ♠ 析构器
  • ♠ 垃圾收集器
    • ♥ 版本变化
  • ♠ 控制垃圾收集的步长
  • ♠ 推送
  • ♠ 结语


♠ 概述

Lua使用自动内存管理,用户可以创建对象,而不能删除对象,解放双手,不需要对内存进行管理

部分情况下需要我们主动辅助Lua去进行垃圾回收


♠ 弱引用表

弱引用的作用就是告诉GC,回收的时候不用考虑这一部分引用,弱引用通过弱引用表来实现

弱引用表通过元表的特殊字段__mode来定义,如下所示__mode设置为k则键是弱引用,值设置为v则表值为弱引用,设置为kv则键值都是弱引用

  • 键为弱引用的弱引用表
a = {}

mt = {__mode = "k"}
setmetatable(a, mt)
  • 值为弱引用的弱引用表
a = {}

mt = {__mode = "v"}
setmetatable(a, mt)
  • 键值均为弱引用的弱引用表
a = {}

mt = {__mode = "kv"}
setmetatable(a, mt)

♥ 示例

我们通过简单的例子来演示对于弱引用的垃圾回收


♣ 弱引用键

首先我们创建一个键为弱引用的表,如下述代码所示,我们简单分析一下

a = {}

mt = {__mode = "k"}
setmetatable(a, mt)

sKey    = {}
sValue  = {}

a[sKey] = sValue
sKey    = {}

-- collectgarbage()

#### <u><font color="#4B97AE" face="微软雅黑" ></font>
for i,v in pairs(a) do
    print(i,v)
end
#### <u><font color="#4B97AE" face="微软雅黑" ></font>
  • 表a通过设置元表mt变成了一个为弱引用的弱引用表
  • 定义了两个空表skeysValue,并表a设置了a[sKey] = sValue
  • 紧随其后去重置了空表sKey = {}

若果我们不设置弱引用表,垃圾回收对结果是没有影响的,表a内包含了以sKey为键,sValue为值的一组键值对

在这里插入图片描述

设置弱引用,执行不执行垃圾回收collectgarbage,输出是如下所示的

在这里插入图片描述

看结果很显然,设置键弱引用后,表a内的键值在手动垃圾回收后都被回收掉了,我们分析一下原因,重点在下图所示的位置

在这里插入图片描述

我们为表a设置了以skey为键的一组键值对后,随即对skey进行了一次重新赋值
第一个声明的表其实已经失去了引用,因为引用它的skey已经重新赋值,新声明的表,虽然都是空表,但从内存地址来说已经不是一个表了
所以在垃圾回收的时候,作为表a键的空表已经失去了除弱引用外的所有引用,那么它就会连带着值被一起回收

在这里插入图片描述


♣ 弱引用值

弱引用值和弱引用键是一样的,在值是弱引用的情况下,如果对应值已经失去了除弱引用外的所有引用,那么在垃圾回收执行后,就会连带着键一起被回收

在这里插入图片描述

注意:只有对象可以从弱引用表中被移除,而像数字和布尔这样的“值”是不可回收

在这里插入图片描述

♠ 析构器

析构器是一种与对象关联的函数,当该对象即将被回收时该函数会被调用

Lua通过元方法_gc实现析构器,如下例所示,在全局变量tbl失去引用被回收后,元方法__gc会被调用

tbl = {x ="oh shit 我无了!"} 

mt = {}
mt.__gc = function(tbl)
    print(tbl.x)
end
setmetatable(tbl, mt) 
tbl = nil

collectgarbage()

在这里插入图片描述

每一个对象的析构器都会精确运行一次如果一个对象直到程序运行结束还没有被回收,那么Lua语言就会在整个Lua拟机关闭后调用它的析构器

注意:元方法__gc是在Lua5.2版本才实现的内容


♠ 垃圾收集器

每一个垃圾收集周期由四个阶段组成:标记(mark)、清理(cleaning)、清除(sweep)和析构(finalization)

  • 标记阶段

根结点集合标记为活跃,根结点集合由Lua语言可以直接访问的对象组成,这个集合只包括注册表,当所有能标记活跃的对象标记完后,标记结束

  • 清理阶段

在这个阶段处理析构器和弱引用表
首先,Lua找到所有需要被析构的对象,标记为复苏状态单独存放
然后,Lua遍历弱引用表并从中移除键或值未被标记的元素

  • 清除阶段

遍历所有对象如果一个对象没有被标记为活跃,则会被清理,之后会清除所有标记,等待下一个一个回收周期

  • 析构阶段

Lua语言调用清理阶段被标记为复苏状态的对象的析构器


♥ 版本变化

在5.1版本之前的垃圾回收会停止主程序,待回收结束再恢复,5.1之后使用了增量式垃圾收集器,不在需要停止主程序

为了保证垃圾收集器的正确性,垃圾收集器中的有些操作具有发现危险改动和纠正所涉及对象标记的内存屏障

Lua5.2引入了紧急垃圾收集当内存分配败时,Lua会强制进行一次完整的垃圾收集 ,然后再次尝试分配


♠ 控制垃圾收集的步长

通过函数collectgarbage可以对垃圾收集器进行一些额外的控制,该函数实际上是几个函数的集合体,通过传递不同参数会有不通效果

参数功能
“stop”停止垃圾收集器,直到使用参数restart再次调用collectgarbage
“restart”重启垃圾收集器
“collect”执行一次完整的垃圾回收,默认这个
“step”执行某些垃圾收集工作
“count”kb为单位返回当前已用内存数
“setpause”控制在一次收集完成后, 多久再开始新的一次回收
“setstepmul”控制对于每分配1KB内存,垃圾收器应该进行多少工作

♠ 推送

  • Github
https://github.com/KingSun5

♠ 结语

若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。

👉 本文属于原创文章,转载请评论留言,并在转载文章头部著名作者出处👈

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

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

相关文章

Unity:sentinel key not found (h0007)

SSD换电脑&#xff0c;unity 编辑器无法打开&#xff1b; 具体步骤&#xff1a; 删除这个路径下的文件 C:\ProgramData\SafeNet 下 Sentinel LDK 打开Windows 的Cmd 命令行&#xff0c;输入编辑器版本下Unity.exe的路径&#xff0c; CD E:\Dev_Env\Unity\Hub\Editor\2020.3.3…

如何将 arduino-esp32 库作为 ESP-IDF 组件使用?

相关文档 arduino-esp32 SDKESP-IDF SDKESP-IDF 软件环境搭建说明Arduino 软件环境使用说明Arduino as an ESP-IDF component &#xff08;官方说明&#xff09; 环境准备 目前&#xff0c;最新 Master 版本的 arduino-esp32 SDK 要求使用 v4.4 版本的 ESP-IDF SDK 软件编译环…

05、Nginx反向代理

一、网关、代理与反向代理&#xff1a; 在Nginx中&#xff0c;网关、代理和反向代理是三种常见的功能&#xff0c;用于转发和处理请求。下面是它们的简要介绍&#xff1a; 网关&#xff08;Gateway&#xff09;&#xff1a; 网关在网络通信中起到中介的作用&#xff0c;将客户…

【视觉SLAM入门】1. 基础知识,运动观测,旋转(旋转矩阵,轴角,欧拉角,四元数)和eigen库基础

"山薮藏疾" 1. 运动与观测1.1 通用运动方程1.2 通用观测方程1.3 对SLAM的认识 2. 三维运动2.1 旋转与平移2.2 变换矩阵2.3 矩阵知识补充2.4 旋转向量2.5 欧拉角2.6 四元数2.7 其他变换 3. 编程基础3.1 链接库说明3.2 eigen库 注&#xff1a; 以后的方程中如未说明&am…

面试官:一千万的数据,要怎么查?

一个老生常谈的问题&#xff0c;SELECT *和SELECT具体字段那个快&#xff1f;在数据量少的时候可能没什么差别&#xff0c;但是数据量达到千万级&#xff0c;差距就显现出来。废话不多说&#xff0c;往下看 ↓。 SELECT * 和 SELECT 具体字段的区别 在 MySQL 中&#xff0c;SE…

批量规范化

✨✨✨ 感谢优秀的你打开了小白的文章 “希望在看文章的你今天又进步了一点点&#xff0c;生活更加美好&#xff01;”&#x1f308;&#x1f308;&#x1f308; 目录 1.批量规范化基本原理 2.批量规范化的使用 2.1对于全连接层 2.2对于卷积层 3.代码实现 3.1方式一 …

26488-24-4,Cyclo(D-Phe-L-Pro),具有良好的生物相容性

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ 【产品描述】 Cyclo(D-Phe-L-Pro)环(D-苯丙氨酸-L-脯氨酸)&#xff0c;环二肽是由两个氨基酸通过肽键环合形成&#xff0c;是自然界中小的环状肽。由于其存在两个酰胺键即四个可以形成氢键的位点&#xff0c;环二肽可以在氢…

商业海外社交媒体营销10步指南 [2023]

如今&#xff0c;社交媒体是任何成功商业战略的重要组成部分。这不是奢侈品&#xff0c;而是必需品。全球有超过 36 亿人使用社交媒体&#xff0c;它是企业展示其产品和服务、建立品牌知名度以及与客户联系的数字游乐场。 但这不仅仅是娱乐和游戏。要在社交媒体上取得成功&…

Golang每日一练(leetDay0114) 矩阵中的最长递增路径、按要求补齐数组

目录 329. 矩阵中的最长递增路径 Longest Increasing Path In A Matrix &#x1f31f;&#x1f31f; 330. 按要求补齐数组 Patching Array &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日…

数据结构--二叉树的性质

数据结构–二叉树的性质 二叉树常考性质 常见考点1: 设非空二叉树中度为0、1和2的结点个数分别为 n 0 、 n 1 和 n 2 &#xff0c;则 n 0 n 2 1 n_0、n_1和n_2&#xff0c;则n_0 n_2 1 n0​、n1​和n2​&#xff0c;则n0​n2​1 n 0 n 2 1 \color{red}n_0 n_2 1 n0​n2​…

图层中大型数据集的分块处理思路

图层中大型数据集的分块处理思路 为改善要素叠加工具&#xff08;如联合和相交&#xff09;的性能和可伸缩性&#xff0c;软件采用了称为自适应细分处理的运算逻辑。当可用的物理内存不足以对数据进行处理时&#xff0c;就会触发系统使用此逻辑。由于保持在物理内存的可用范围…

助力企业完成等保2.0的重要工具

在当今数字化时代&#xff0c;企业面临着越来越多的网络安全威胁和数据泄露风险。为了保护敏感信息和维护业务的连续性&#xff0c;许多企业正在积极采取措施来实施等保2.0标准。在这一过程中&#xff0c;EventLog Analyzer作为一种全面的安全信息与事件管理解决方案&#xff0…

swagger2word使用(将swagger2转化为word)

开源项目地址 https://github.com/JMCuixy/swagger2word 项目使用 1、项目拉下来以后先修改application.xml配置文件红框内容&#xff0c;将其修改为要换为自己swagger文档的地址 2、运行项目后输入地址http://127.0.0.1:8080/toWord 即可下载word文档

结构体和数据结构--共用体

共用体&#xff0c;也称联合&#xff08;Union&#xff09;&#xff0c;是将不同类型的数据组织在一起共同占用同一段内存的一种构造数据类型。共用体与结构体的类型声明方法类似&#xff0c;只是关键字变为了Union。 例题&#xff1a;演示共用体所占内存字节数的计算方法 #i…

如何用手机制作3D人物模型素材

3D人物模型素材是现代3D游戏和电影制作中必不可少的一部分。它们是数字艺术家和设计师们用来创造逼真世界的关键。3D人物模型素材是用计算机程序制作的虚拟人物&#xff0c;可以被用于电影、电视、游戏和虚拟现实应用中。它们可以被用来代替实际演员&#xff0c;也可以被用来创…

小程序蓝牙通信

蓝牙通信能力封装 一开始是根据uniapp提供的蓝牙api写的蓝牙方法&#xff0c;之后发现复用性&#xff0c;以及一些状态的监听存在缺陷&#xff0c;之后整理成了类。这样复用性以及状态监听的问题就解决了。 蓝牙组件 创建蓝牙组件的类 单例模式是为了保证蓝牙长连接&#xff0…

前端(一)——前端开发遇到的普遍问题以及解决策略

&#x1f604;博主&#xff1a;小猫娃来啦 &#x1f604;文章核心&#xff1a;前端开发遇到的普遍问题以及解决策略 前端十万个为什么&#xff1f; 有人说vue框架是基于mvvm实现的&#xff1f;这种说法对吗&#xff1f; mvc和mvvm的区别是什么&#xff1f; mvvm是否是mvc的升…

内容文本生成二维码用excel表格导出(java)

内容文本生成二维码用excel表格导出(java) //若有问题可留言 效果如下: import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map;import org.apache.po…

大厂股权就是这么“坑”,150万股票到账前被优化,损失惨重

某网友发文称&#xff1a;“自己还有47天就可以解锁股权&#xff0c;到时就有150万的股票到账&#xff0c;结果接到公司裁员通知&#xff0c;实在是淌血&#xff0c;我能反抗吗&#xff1f;” 对这我只能说&#xff0c;公司卡的就是这个点。所以大家在找工作的时候&#xff0c;…

SparkJDBC性能优化指南

前言 本文以Mysql为例。Spark作为一种强大且广泛应用于大数据处理的分布式计算框架,有着出色的性能和可伸缩性。在使用Spark处理大规模数据时,往往需要与关系型数据库MySQL进行交互。然而,由于MySQL和Spark本身的特性之间存在一些差异,直接使用Spark读写MySQL的默认配置可…