最近互联网的好多巨头公司都在研究VR,其实VR这个东西体验的时候有点像是一圈人围着抽一支大麻一样。为什么这么说呢,戴着设备的人在那边抽搐,旁边不知所以。完事后体验的人脱下设备交给下一位,如有虚脱,又意犹未尽。哈哈哈哈哈哈哈哈哈哈哈哈...
废话不多说,今天来讲一下lua中垃圾的收集。lua提供了一个自动的内存管理。这个意思就是你不需要关心创建新对象的分配内存问题,也不需要关心这些对象不再使用时的主动释放内存。lua通过运行一个垃圾收集器来进行自动管理内存,以此一遍又一遍的回收不再使用的对象。lua中所有对象都被自动管理,包括之前谈到的table、userdata、function、thread、string。
lua实现了一个增量标记清楚的收集器。它用两个数字来控制垃圾的生命周期:garbage-collector pause和garbage-collector step multiplier。
先说第一个:garbage-collector pause控制了收集器在开始一个新的收集周期之前要等待多久。数字越小,工作频率越大。小于1的值意味着收集器在新的周期开始时不再等待。当值为2的时候意味着在总使用内存数量达到原来的两倍时在开启新的周期。
第二个:garbage-collector step multiplier控制了收集器相对内存分配的速度。数字越大,工作频率越大,和上面谈到的恰好相反。小于1的值会使收集器工作的非常慢,可能导致收集器永远都结束不了当前周期。缺省值为2,这意味着收集器将以内存分配器的两倍速运行。
具体的使用方法可以参考如下:
collectgarbage("setpause", 200)
collectgarbage("setstepmul", 200)
具体函数和参数的含义将在后面的章节中介绍。
垃圾收集的元方法:
使用C API, 你可以给userdata设置一个垃圾收集的元方法。这个元方法也被称为结束子。结束子允许你使用额外的资源管理器和lua的内存管理器协同工作(比如关闭文件、网络连接、数据库连接,也可以说释放你自己的内存)。
一个userdata可被回收,若它的metatable中有__gc这个域,垃圾收集器就不立即回收它。取而代之的是,lua把它们放到一个列表中。收集结束后,lua针对列表中的每个userdata执行了下面这个函数的等价操作:
function gc_event( udata )
local h = metatable(udata).__gc
if h then
h(udata)
end
end
在每个垃圾收集周期的结尾,每个在当前周期被收集起来的userdata的结束子会以它们构造时的逆次序调用。也就是说,收集列表中,最后一个在程序中被创建的userdata的结束子会被第一个调用。
弱表(Weak Table):
在weak table这个表中的元素都会被弱引用。弱引用将被垃圾收集器忽略掉,如果对一个对象的引用只有弱引用,垃圾收集器将回收这个对象。
weak table的键和值都可以是weak的。如果一个table只有键是weak的,那么将运行收集器回收他们的键,但是会阻止收集器回收他们对应的值。而一个table的键和值都是weak时,就即允许收集器回收键,又允许收集器回收值。那么如何把一个对象弱化呢?看下面的例子:
function Weakify( obj )
local weak = setmetatable({content = obj}, {__mode = "v"})
return function() return weak.content end
end
上面这个例子,我们用到了__mode这个域。__mode域中是一个包含字符“v”的字符串,这时table的值就是weak的。如果__mode域中是一个包含字符“k”的字符串时,table的键就是weak的。
在你把一个table当做一个metatable使用之后,就不能再使用__mode域的值。否则,受这个metatable控制的table的weak行为就成了未定义的。
这篇正文内容就先讲这么多。今天六点下班之后和同事一起去看电影去了,《奇幻森林》,看了之后感觉还不错,推荐!!!
本文参考lua手册 http://www.lua.org/manual/5.3/manual.html