Lua五:”collectgarbage”、 弱引用table、析构器「建议收藏」

Lua五:”collectgarbage”、 弱引用table、析构器「建议收藏」Lua具有自动内存回收机制,但是垃圾收集器只能回收那些它认为是垃圾的东西,不会回收那些用户认为是垃圾的东西。比如将一个对象放在一个数组中但没有用时,它就无法被回收,这是因为即使当前没有其他地方在使用它

大家好,又见面了,我是你们的朋友全栈君。

       Lua具有自动内存回收机制,但是垃圾收集器只能回收那些它认为是垃圾的东西,不会回收那些用户认为是垃圾的东西。比如将一个对象放在一个数组中但没有用时,它就无法被回收,这是因为即使当前没有其他地方在使用它,但数组仍引用着它,除非用户告诉Lua这项引用不应该阻碍此对象的回收,否则Lua是无从得知的。

       Lua垃圾回收函数collectgarbage,这个函数是垃圾回收机制的一个通用接口,其第一个参数是字符串,代表操作类型,第二个参数只有某些操作有,是该操作所需要的参数。其原型:collectgarbage ([opt [, arg]])

操作类型:

  • “collect”:执行一个完整的垃圾回收周期,这是一个默认的选项。
  • “stop”:停止垃圾收集器(如果它在运行),直到再次使用操作为”restart”的圾回收函数collectgarbage。
  • “restart”:将重新启动垃圾收集器(如果它已经停止)。
  • “count”:返回当前使用的的程序内存量(单位是Kbytes)。
  • “step”:执行垃圾回收的步骤,这个步骤的大小由参数arg(较大的数值意味着较多的步骤)以一种不特定的方式来决定,如果你想控制步骤的大小,你必须实验性的调整参数arg的值,如果这一步完成了一个回收周期则函数返回true。
  • “setpause”:第二个参数pause 用于控制垃圾收集器在一次收集完成后等待多久再开始新的一次收集。当值为零时表示 Lua语言在上一次垃圾回收结束后立即开始一次新的收集。当值为200%时表示在重启垃圾收集器前等待内存使用翻番。如果想使消耗更多的CPU时间换取更低的内存消耗,那么可以把这个值设得小一点。通常,我们应该把这个值设在О到200%之间。
  • “setstepmul”:参数stepmul控制对于每分配1KB内存,垃圾收集器应该进行多少工作。这个值越高,垃圾收集器使用的增量越小。一个像100000000%一样巨大的值会让收集器表现得像一个非增量的垃圾收集器。默认值是 200%。低于100%的值会让收集器运行得很慢,以至于可能一次收集也完不成。

       两个参数pause和stepmul控制着垃圾收集器的角色。任何垃圾收集器都是使用CPU时间换内存空间。在极端情况下,垃圾收集器可能根本不会运行。但是,不耗费CPU时间是以巨大的内存消耗为代价的。在另外一种极端的情况下,收集器可能每进行一次赋值就得运行一次完整的垃圾收集。程序能够使用尽可能少的内存,但是是以巨大的CPU消耗为代价的。pause 和stepmul的默认值正是试图在这两个极端之间找到的对大多数应用来说足够好的平衡点。

       选项setpause的使用方法:collectgarbage(“setpause”, 200),表示当收集器在总使用内存数量达到上次垃圾收集时的两倍时再开启新的收集周期。

       选项setstepmul的使用方法:collectgarbage(“setstepmul”, 200),表示垃圾收集器的运行速度是内存分配的2倍,如果此值小于100可能会导致垃圾回收不能形成完整的周期。

 

       table中有key和value,这两者都可以包含任意类型的对象。通常,垃圾收集器不会回收一个可访问table中作为key或value的对象。也就是说,这些key和value都是强引用,它们会阻止对其所引用对象的回收。在一个弱引用table中,key和value是可以回收的。

       弱引用table(weak table)是用户用来告诉Lua一个引用不应该阻碍对该对象的回收。所谓弱引用,就是一种会被垃圾收集器忽视的对象引用。如果一个对象的引用都是弱引用,该对象也会被回收。

       弱引用table有3种类型:1、具有弱引用key的table;2、具有弱引用value的table;3、同时具有弱引用key和value的table;

       table的弱引用类型是通过其元表中的__mode字段来决定的。这个字段的值应为一个字符串:如果包含’k’,那么这个table的key是弱引用的;如果包含’v’,那么这个table的value是弱引用的;

       弱引用table的一个例子,这里使用了collectgarbage函数强制进行一次垃圾收集:

 1 a = {}
 2 setmetatable(a, {__mode='k'})
 3 
 4 key = {}
 5 a[key] = 'key1'
 6 
 7 key = {}
 8 a[key] = 'key2'
 9 
10 collectgarbage()

      该段代码“collectgarbage()”运行前,表a同时存在key为{}和value为’key1’和’key2’的对象,“collectgarbage()”运行后,只存在key为{}和value为’key2’的对象。

 

      析构器_gc简单来说,就是当一个table的元表中存在_gc时,就会在这个lua table被gc释放掉之前,调用的函数。不过,在5.2之前,_gc只能用在userdata中,而5.2及5.2之后,table也可以用__gc了。

 1 function class(name, super)
 2    ...
 3     -- 析构函数
 4     if cls.dtor then
 5         cls.dtor = function(self) end
 6     end
 7 
 8     cls.__meta = {__index = cls, __gc = function(self) self:dtor() end}
 9     cls.new = function(...)
10         local obj = setmetatable({}, cls.__meta)
11         obj:ctor(...)
12         return obj 
13     end
14     return cls
15 end

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/154976.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 爱玩吧提供10G国外免费PHP空间「建议收藏」

    爱玩吧提供10G国外免费PHP空间「建议收藏」爱玩吧提供10G国外免费PHP空间爱玩吧香港空间:不再开放免费空间申请。大家就去用免费国外不限制空间申请Yhfx.ml免费空间服务由idc.aiwanba.net提供 免费空间套餐每月流量 100GB空间容量10GB控制面板演示

    2022年9月21日
    4
  • 纯css3手机页面图标样式代码

    全部图标:http://hovertree.com/texiao/css/19/先看效果:或者点这里:http://hovertree.com/texiao/css/19/hoverkico.htm简

    2021年12月21日
    51
  • resnet18[通俗易懂]

    resnet18[通俗易懂]前言在前篇vgg16之后,无法成功训练vgg16,发现是自己电脑可用的显存太低了,遂放弃。在2015ILSVRC&COCO比赛中,何恺明团队提出的Resnet网络斩获第一,这是一个经典的网络。李沐说过,如果要学习一个CNN网络,一定是残差网络Resnet。与VGG相比,Resnet则更加出色,为后续的研究做下铺垫这是Resnet论文翻译参考链接:https://blog.csdn.net/weixin_42858575/article/details/93305238在之前的神经

    2022年5月26日
    69
  • 0x00和’0′[通俗易懂]

    0x00和’0′[通俗易懂]往往小问题才会折腾很久。msmset((void*)virt,0x00,PAGE_SIZE)和msmset((void*)virt,‘0’,PAGE_SIZE)区别就在于0x00只是为了强调就是数字0,就是为了ASCII码转换的数字0!不是字符‘0’!如果手误将数字0写作字符‘0’,那就达不到用‘\0’清空字符串的目的了。所以最近在内核中分配页的时候总是判断最后一级页表项出错,原来是在allo

    2025年7月5日
    1
  • vmware10.0密钥_windows10永久激活密钥

    vmware10.0密钥_windows10永久激活密钥VMwareWorkstation是功能最强大的热门虚拟机软件,现已自带原生简体中文。用户可在在虚拟机同时运行各种操作系统,进行开发、测试、演示和部署软件,虚拟机中复制服务器、台式机和平板环境,每个虚拟机可分配多个处理器核心、千兆字节的主内存和显存。VMwareWorkstation™11延续了VMware的传统,即提供技术专业人员每天在使用虚拟机时所依赖的领先功能和性能。借

    2025年11月16日
    1
  • Matlab插值方法大全

    Matlab插值方法大全命令1 interp1功能一维数据插值(表格查找)。该命令对数据点之间计算内插值。它找出一元函数f(x)在中间点的数值。其中函数f(x)由所给数据决定。x:原始数据点Y:原始数据点xi:插值点Yi:插值点格式(1)yi=interp1(x,Y,xi)返回插值向量yi,每一元素对应于参量xi,同时由向量x与Y的内插值决定。参量x指定数据Y的点。若Y为一矩阵,则按Y的

    2022年6月4日
    111

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号