首页 > 其他分享 >Lua的垃圾回收

Lua的垃圾回收

时间:2024-04-08 18:22:43浏览次数:26  
标签:构器 收集器 对象 回收 Lua 垃圾 -- 引用

1 弱引用表

1.1 弱引用

如果一个对象被引用,那么垃圾回收器不会回收该对象,这就是“强引用”。与“强引用”对应,如果一个对象没有被引用,或者仅被“弱引用”,那么垃圾回收器会忽视弱引用,回收该对象。

1.2 弱引用表

指元素均被“弱引用”的表。
我们无法通过变量直接“弱引用”一个对象,我们需要通过指定一张表为弱引用表,然后将对象添加到表中,通过表来“弱引用”多个对象。
表由键值对组成,一般情况下键和值都是被“强引用”;在一个弱引用表中,键和值都可以是被“弱引用”的,这就意味着有三种类型的弱引用表:具有弱引用键的表、具有弱引用值的表,同时具有弱引用键和值的表,不论是哪种类型的弱引用表, 要有一个键或值被回收了,那么对应的整个键值对都会被从表中删除。

1.3 “弱引用”对象的方法

点击查看代码
--1. 首先我们指定a表为弱引用表
a = {} 
--元表.__mode表示该表是否为弱引用表,"k":弱引用键,"v":弱引用值,"kv":弱引用键值
mt = {__mode ="v"}      
setmetatable(a, mt)     --现在a的值是弱引用的了

--2. 创建一个对象,当前该对象被b“强引用”
local b = "object~~"

--3.向弱引用表添加一个对象
a[1] = b
collectgarbage()            --强制执行垃圾回收
print(tostring(a[1]))       --> object~~

--4.删除对象的所有强引用,垃圾回收后,该对象被彻底回收,弱引用表也会删除该对象的引用
b = nil
collectgarbage()            --强制执行垃圾回收
print(tostring(a[1]))       --> nil

2 瞬表

瞬表是一种特殊的弱引用表,一个具有弱引用键和强引用值的表被Lua作为瞬表,它的特殊之处在于:如果瞬表的值引用了键,在不做特殊处理的情况下,即使表外部没有强引用,垃圾收集器也不会回收键。
Lua在5.2中引入瞬表的概念,并做了特殊处理,使得垃圾收集器否认表内部对弱引用键的强引用,正确回收键。Lua5.1依然存在这个问题。

3 析构器

析构器与构造器相似,是对象的一个特殊函数,析构器不会被开发人员主动调用,而是在垃圾收集器回收对象时,被垃圾收集器调用。
3.1 定义析构器

点击查看代码
--通过元方法__gc实现析构器
local o = {x="obj dead."} 
setmetatable(o, {__gc = function(o) print(o.x) end})     --析构器的参数正式被析构的对象
o = nil
collectgarbage()    --> obj dead.

为对象设置元表时,如果元表定义了析构器,那么垃圾收集器会将对象标记为“需要进行析构处理”,放入特定队列回收对象时,将根据该标记决定是否调用对象的析构器,这保证了每个对象的析构器都会精确地运行且只运行一次。
定义析构器的坑:
为对象设置的元表没有析构器,即使后续向元表增加__gc元方法,垃圾收集器也不会做任何处理。

点击查看代码
local o = {x="obj dead."} 
local mt = {}        
setmetatable(o, mt)    --元表没有定义析构器
mt.__gc = function(o) print(o.x) end     --追加定义析构器
o = nil
collectgarbage()    --> print nothing    --追加定义的析构器没有被调用

3.2 复苏

当垃圾回收处于析构阶段,由于析构器的参数正式被析构的对象,因此,该对象及其字段引用的其他对象,会在析构期间重新活跃,这意味着,上述例子中,在o的析构器调用前,不能释放x的内存。

4 垃圾收集器

Lua 语言通过垃圾收集器(garbage collector)自动地删除成为垃圾的对象。
Lua语言使用的是一个简单的标记-清除(mark-and-sweep)式垃圾收集器,这种收集器又被称为“全局暂停(stop-the-world)”式的收集器,意味着垃圾收集器在需要时,会中断主程序的运行来执行一次完整的垃圾收集周期, 每一个垃圾收集周期由四个阶段组成:标记(mark)、清理(cleaning)、清除(sweep)、析构(finalization)。
标记:当对象被变量或其他对象的字段引用时,意味着该对象是程序可达的,垃圾收集器将这样的对象标记为活跃。(垃圾收集器不会标记被弱引用的对象)
清理:针对弱引用表,清理非活跃对象;针对需要执行析构器的非活跃对象,将对象放入析构列表,该列表会在析构阶段用到。
清除:上一次GC中需要回收的对象,在这一次GC的清除阶段释放其内存。
析构:遍历析构列表,按照早前“需要进行析构处理”标记的标记顺序,调用对象的析构器,这个阶段没有释放任何对象的内存,析构器内可以安全地访问任何对象成员。在下一次GC才会将本次GC析构完成的对象从内存中删除。这意味着,如果想保证我们程序中的所有垃圾都被真正释放,那么必须调用collectgarbage两次,第二次调用才会释放第一次调用中被析构的对象内存。
以上是Lua5.0的垃圾收集器工作方式,后续Lua对其进行了优化。
Lua5.1使用了增量式垃圾收集器(incremental collector),这种垃圾收集器像老版的垃圾收集器一样执行相同的步骤,但是不需要在垃圾收集期间停止主程序的运行,它与主程序交替运行。
Lua5.2引入了紧急垃圾收集(emergency collection)。当内存分配失败时,Lua会强制执行一次完整的垃圾收集,然后再尝试分配。(此处完整的垃圾收集会释放本次GC中析构完成的对象,不再留给下次GC)

5 控制垃圾收集器

通过函数collectgarbage可以对垃圾收集器做些额外的控制:
collectgarbage ([opt [, arg]])
第一个参数是一个可选字符串,指定对垃圾收集器做何种控制;第二个参数是对指定的控制补充额外参数。
collectgarbage("collect"): 做一次完整的垃圾收集循环。
collectgarbage("count"): 返回当前已使用的内存大小,以KB为单位。
collectgarbage("restart"): 重启垃圾收集器。
collectgarbage("stop"): 停止垃圾收集器,直到调用collectgarbage("restart")
collectgarbage("setpause"): 将 arg 设为收集器的间歇率。 返回旧的间歇率值。
collectgarbage("setstepmul"): 将 arg 设为收集器的步进倍率。 返回旧的步进倍率值。

标签:构器,收集器,对象,回收,Lua,垃圾,--,引用
From: https://www.cnblogs.com/littlelz/p/18122103

相关文章

  • 基于STM32单片机智能垃圾桶红外感应雨滴检测语音设计21-766
    21-766、STM32智能垃圾桶设计-E18-KEY-红外对管-ISD1820-水滴-电磁锁产品功能描述:本设计有STM32F103C8T6单片机核心板电路+红外避障传感器电路+按键电路+红外对管电路+ISD1820语音模块电路+水滴传感器电路+电磁锁电路组成。1、通过红外避障传感器和按键均可以控制电磁锁的开......
  • 垃圾回收机制
    垃圾回收机制(GC)定义:是python自带的一种机制用来回收变量值所占的内存空间堆heap堆区:变量值存放区域栈stack栈区:变量名和值内存地址关联的区域小整数池​ [-5,256]作用:引用计数为主变量值被变量名引用的次数标记清除为辅当一个变量值被引用时,Python自带......
  • ETL工具-nifi干货系列 第九讲 处理器EvaluateJsonPath,根据JsonPath提取字段
    1、其实这一节课本来按照计划一起学习RouteOnAttribute处理器(相当于java中的ifelse,switchcase控制语句),但是在学习的过程中遇到了一些问题。RouteOnAttribute需要依赖处理器EvaluateJsonPath,所以本节课我们一起来学习下EvaluateJsonPath处理器。如下图所示: 本节课的示例依然......
  • oracle 数据库精简模式磁盘空间回收处理
            最近遇到的项目中,需要部署几套oracle19cRAC数据库,在进行存储磁盘卷划分的时候,发现只能分配精简卷模式的磁盘,出于性能以及安全考虑,咨询存储原厂答曰该powerstore存储只支持精简磁盘卷模式。    自oracle12c开始,asm开始支持精简卷模式,asm磁盘组......
  • 基于SpringBoot的“垃圾分类网站”的设计与实现(源码+数据库+文档+PPT)
    基于SpringBoot的“垃圾分类网站”的设计与实现(源码+数据库+文档+PPT)开发语言:Java数据库:MySQL技术:SpringBoot工具:IDEA/Ecilpse、Navicat、Maven系统展示系统功能结构图系统功能界面图用户登录、用户注册界面图4垃圾图谱界面图管理员登录界面图用户......
  • 基于深度学习的生活垃圾智能分类系统(微信小程序+YOLOv5+训练数据集+开题报告+中期检查
    摘要        本文基于Python技术,搭建了YOLOv5s深度学习模型,并基于该模型研发了微信小程序的垃圾分类应用系统。本项目的主要工作如下:    (1)调研了移动端垃圾分类应用软件动态,并分析其优劣势;分析了深度学习在垃圾分类领域的相关应用,着重研究了YOLO系列的工作原......
  • python的垃圾回收
    引用计数器为主,标记清除和分代回收为辅1引用计数器在python程序运行时,会根据数据类型的不同找到其对应的结构体,根据结构体中的字段来进行创建相关的数据,然后将对象添加到refchain双像链表中,每个对象中的ob_refcnt就是引用计算器,值默认是为1,当有其他的变量引用对象时,引用......
  • 基于深度学习的生活垃圾检测与分类系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)
    摘要:在本博客中,我们深入探讨了基于YOLOv8/v7/v6/v5等深度学习模型的生活垃圾检测与分类系统。作为核心,我们采用了YOLOv8算法,并与YOLOv7、YOLOv6、YOLOv5进行了综合性能对比,以评估各个版本在生活垃圾检测与分类任务上的表现和效率。我们详细介绍了相关领域的国内外研究现状,包括但不......
  • Python程序设计 垃圾回收机制&鸭子类型
    1.简介引用计数(python默认):记录该对象当前被引用的次数,每当新的引用指向该对象时,它的引用计数ob_ref加1,每当该对象的引用失效时计数ob_ref减1,一旦对象的引用计数为0,该对象立即被回收标记清除:第一段给所有活动对象标记,第二段清除非活动对象分代回收:python将内存根据对象的存......
  • 基于深度学习的景区垃圾识别系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)
    摘要:本文深入研究了基于YOLOv8/v7/v6/v5的景区垃圾识别系统,核心采用YOLOv8并整合了YOLOv7、YOLOv6、YOLOv5算法,进行性能指标对比;详述了国内外研究现状、数据集处理、算法原理、模型构建与训练代码,及基于Streamlit的交互式Web应用界面设计。在Web网页中可以支持图像、视频和实时摄......