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

这篇具有很好参考价值的文章主要介绍了Lua学习笔记:浅谈对垃圾回收的理解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言
本篇在讲什么

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

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

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

本篇的特色

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

Lua学习笔记:浅谈对垃圾回收的理解,lua学习笔记,lua,学习,笔记
★提高阅读体验★

👉 ♠ 一级标题 👈

👉 ♥ 二级标题 👈

👉 ♣ 三级标题 👈

👉 ♦ 四级标题 👈


♠ 概述

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为值的一组键值对

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

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

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

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

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

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

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


♣ 弱引用值

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

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

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

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

♠ 析构器

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

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学习笔记,lua,学习,笔记

每一个对象的析构器都会精确运行一次如果一个对象直到程序运行结束还没有被回收,那么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

♠ 结语

若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。文章来源地址https://www.toymoban.com/news/detail-541855.html

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

到了这里,关于Lua学习笔记:浅谈对垃圾回收的理解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 浅谈对线程的理解

    在Python中,想要实现多任务还可以使用多线程来完成。 进程是分配资源的最小单位 , 一旦创建一个进程就会分配一定的资源 , 就像跟两个人聊QQ就需要打开两个QQ软件一样是比较浪费资源的 . 线程是font color=\\\"red\\\"程序执行的最小单位/font , 实际上进程只负责分配资源 , 而利用这

    2024年04月10日
    浏览(52)
  • 【Lua学习笔记】Lua入门

    (不是教程,推荐有编程基础的人观看本文) 文中主要包含了对菜鸟教程中的一些学习理解,个人感觉Lua语言和Python很多地方相似 以下大部分代码和表格摘抄自菜鸟教程 数据类型 描述 nil 只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)(类似与Null或者

    2024年02月15日
    浏览(37)
  • 【Lua学习笔记】Lua进阶——协程

    协程是一种并发操作,相比于线程,线程在执行时往往是并行的,并且线程在创建销毁执行时极其消耗资源,并且过长的执行时间会造成主进程阻塞。而协程可以以并发时轮值时间片来执行,优点是不会阻塞,消耗资源少,可以手动控制。至于协程和线程的区别,什么是并发

    2024年02月15日
    浏览(94)
  • 【Lua学习笔记】Lua进阶——函数和闭包

    使用函数嵌套的用法,我们可以将另一个函数作为返回值,但是返回函数作为一个值是要被赋值给其他变量的,所以return时不能起名(赋值)为其他变量名。 推荐阅读深入Lua:函数和闭包 在函数嵌套中,我们需要接触一个叫做闭包的概念 这就是一个闭包,它由一个函数和该

    2024年02月15日
    浏览(56)
  • 【Lua学习笔记】Lua进阶——Table(3) 元表

    接上文 Q:为什么要使用元表? A:在Lua中,常常会需要表与表之间的操作。元表中提供了一些元方法,通过自定义元方法可以实现想要的功能,相当于面向对象中给你一系列方法让你重载。 使用下列代码设置元表: 通常在元表中操作分为三步: 操作子表 检测是否有元表 若

    2024年02月15日
    浏览(37)
  • 【Lua学习笔记】Lua进阶——Table,迭代器

    在【Lua学习笔记】Lua入门中我们讲到了Lua的一些入门知识点,本文将补充Lua的一些进阶知识 在上篇文章的最后,我们指出通过查询_G的字符索引,发现table.insert实际上是一个名为table的table结构里的索引指向的函数 实际上不仅它,所有的函数,模块,全局变量,元表 😅😅😅

    2024年02月15日
    浏览(36)
  • 【Lua学习笔记】Lua进阶——Require,三目运算

    这是文件 aaa.lua 的内容 这是文件 example.lua 的内容 可以看到,在使用require之后,会直接对其他文件进行调用执行。而且我们可以直接访问它的全局变量,并且发现我们的全局变量被覆盖了,而它的局部变量就像private一样,不能被这个文件访问。 从 package.loaded 这个方法我们可

    2024年02月15日
    浏览(51)
  • 【Lua学习笔记】Lua进阶——Table(4)继承,封装,多态

    现在我们可以像面向对象一样,new一个对应基类的对象了。但是这里的new也不完全相似与面向对象的new,例如我们可以这样做: 我们在封装Object类的时候可完全没有name这个索引,而在Lua中我们new了一个新对象,还能新加入一些变量和方法,这些特性明显是继承了父类的子类才

    2024年02月15日
    浏览(51)
  • Lua学习笔记:require非.lua拓展名的文件

    前言 本篇在讲什么 Lua的require相关的内容 本篇需要什么 对 Lua 语法有简单认知 对 C++ 语法有简单认知 依赖 Visual Studio 工具 本篇的特色 具有全流程的 图文教学 重实践,轻理论,快速上手 提供全流程的 源码 内容 ★提高阅读体验★ 👉 ♣ 三级标题 👈 👉 ♦ 四级标题 👈 想

    2024年02月07日
    浏览(41)
  • 浅谈对ASP.NET MVC(微软Web开发框架)的理解

    今天来总结下y2扩展就业的课程使用asp.netmvc开发企业级应用自学成果。首先ASP.NET是Microsoft公司.NetFramwork框架的一个动态网页开发的核心技术集,他可以帮助.net方向的动态web开发人员快速高效制作动态网页交互,同样支持jquery,js和h5c3,以及实现异步请求服务器达到无刷新效

    2024年02月03日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包