因为受到经济危机的影响,我在 bokee.com 的博客可能随时出现无法访问的情况;因此将2005年到2006年间在 bokee.com 撰写的博客文章全部迁移到 csdn 博客中来,本文正是其中一篇迁移的文章。
3.7 - 控制垃圾收集机制
Lua使用两个数值来控制垃圾收集机制:count和threshold(参考2.9)。count表示Lua总计使用了多少内存;当数值达到threshold,Lua就运行垃圾收集器。之后,更新count,并设置threshold为count的两倍。
你可以通过下列函数存取count和threshold的当前值:
int lua_getgccount (lua_State *L);
int lua_getgcthreshold (lua_State *L);
它们都返回以千字节(Kbyte)为单位的对应值。你也可用下面的函数设置threshold:
void lua_setgcthreshold (lua_State *L, int newthreshold);
同样地,newthreshold也以千字节(Kbyte)为单位。当你调用这一函数,Lua将设置新的threshold并立即检查字节计数器。如果新的threshold小于字节计数器,Lua将马上运行垃圾收集器。特别地,lua_setgcthreshold(L,0)用以强制执行垃圾收集。当垃圾收集之后,将依前面的规则设置新的threshold。
3.8 - 用户数据类型
userdata(用户数据类型)是C值在Lua中的描述。Lua支持两种userdata,完全用户数据类型(full userdata)和轻量级用户数据类型(light userdata)。
一个full userdata是对一块内存的描述。它是一个对象(象表一样):你必须创建它,它能拥有自己的元表,当它被收集的时候你也能够检测到。一个full userdata只和自己相等(根据原始的相等规则)。
一个light userdata是对一个指针的描述。它是一个值(象数字一样):你不必创建它,它也没有元表,它也不会被收集(因为它从未被创建)。一个light userdata和任何拥有相同的C地址的其它light userdata相等。
在Lua代码中,没有办法检测一个userdata是完全还是轻量级的;它们有相同的数据类型——userdata。在C代码中,lua_type返回LUA_TUSERDATA表明是full userdata,LUA_TLIGHTUSERDATA表明是light userdata。
你能够通过下面这个函数来创建一个full userdata:
void *lua_newuserdata (lua_State *L, size_t size);
这一函数申请一块通过size指定大小的内存,然后把一个新的带有这块内存的地址的userdata压入堆栈,返回内存地址。
向堆栈压入light userdata可以使用lua_pushlightuserdata(参考3.6)。
使用lua_touserdata可以得到一个userdata值。当这个函数应用到一个full userdata上时,它返回这一块内存的地址;当应用到一个light userdata上时,返回指针;当应用在非用户数据类型值上时,它返回NULL。
当Lua收集一个userdata的时候,如果有的话,会调用它的gc元方法,然后释放userdata对应的内存。
3.9 - 元表
下列函数可用以操作一个对象的元表:
int lua_getmetatable (lua_State *L, int index);
int lua_setmetatable (lua_State *L, int index);
lua_getmetatable把给定对象的元表压入堆栈。如果索引无效或者对象没有元表,返回0并且不向堆栈中压入任何东西。
Lua_setmetatable把一个表出栈,把它置为新元表,并将其设置为指定对象的元表。Lua_setmetatable在给定对象不能设置元表的时候返回0(当对象既不是用户数据类型也不是表的时候会出现这种情况);并仍会将这个表出栈。