Lua垃圾回收机制

collectgarbage("collect");--(垃圾收集释放内存)
local count = collectgarbage("count");--(垃圾统计所占内存)
print(">>>>>>>>>>>>>>>>>>>>>>>>>>count111   ",count);

local list = {};
for i = 1,100 do 
	local testList = {};
	testList[1],testList[2] = 10000 + i,32 + i;
	list[testList[1]] = testList[2];
end

print(">>>>>>>>>>>>>>>>>>>>>>>>>>count222   ",collectgarbage("count"));
--list = nil;
collectgarbage("collect");
print(">>>>>>>>>>>>>>>>>>>>>>>>>>count333   ",collectgarbage("count"));

在这里插入图片描述
从结果上看出,局部变量被回收了。list却没有被回收。当把list = nil时,请看下面结果。
在这里插入图片描述
当把list = nil时也会被collectgarbage(“collect”)给回收掉。

lua垃圾回收机制:

lua虽然会自己回收无用数据,但同时它还提供了回收函数——collectgarbage()。它的函数原型为:

collectgarbage(opt,[,arg])

其中opt参数有下面7种操作:
1、collectgarbage(“stop”):停止垃圾收集器的运行。 在调用重启前,收集器只会因显式的调用运行。

2、collectgarbage(“restart”): 如果垃圾收集器已经停止,将重新启动它。

3、collectgarbage(“collect”):执行一次全垃圾收集循环,默认执行此操作。

4、collectgarbage(“count”):以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分,所以只需要乘上 1024 就能得到 Lua 使用的准确字节数(除非溢出)。

5、collectgarbage(“step”):单步运行垃圾收集器。 步长”大小”由 arg 控制。 传入 0 时,收集器步进(不可分割的)一步。 传入非 0 值, 收集器收集相当于 Lua 分配这些多(K 字节)内存的工作。 如果收集器结束一个循环将返回 true 。

6、collectgarbage(“setpause”):将 arg/100设为收集器的间歇率。返回 间歇率 的前一个值。默认为200。控制了收集器在开始一个新的收集周期之前要等待多久。 随着数字的增大就导致收集器工作工作的不那么主动。小于 1 的值意味着收集器在新的周期开始时不再等待。 当值为 2 的时候意味着在总使用内存数量达到原来的两倍时再开启新的周期。

7、collectgarbage(“setstepmul”): 返回 步进倍率 的前一个值。
作为步长的增幅(即新步长=旧步长*arg/100);并返回设置前的值。默认为200。控制了收集器的工作速度,这个速度是一个相对于内存分配的速度。更大的数字将导致收集器工作的更主动的同时,也使每步收集的尺寸增加。小于 1 的值会使收集器工作的非常慢,可能导致收集器永远都结束不了当前周期。
缺省值为200%,这意味着收集器将以内存分配器的两倍速运行。

总结一: 如何监测Lua的编程产生内存泄露:

1. 针对会产生泄露的函数,先调用collectgarbage(“count”),取得最初的内存使用
2. 函数调用后, collectgarbage(“collect”)进行收集, 并使用collectgarbage(“count”)再取得当前内存, 最后记录两次的使用差
3. 从test的收集可看到, collectgarbage(“collect”)被调用,并不保证一次成功, 所以, 大可以调用多次

**

总结二: 如何避免Lua应用中出现的内存使用过大行为:

**

1. 当然是代码实现不出现泄露
2. 在测试中,其实还发现, Lua中被分配的内存,其实并不会自动回收(个人估计要么就是Lua虚拟机没有做这个事情,要么就是回收的时机是在C层), 所以, 为了避免内存过大, 应用的运行时,可能需要定期的(调用collectgarbage(“collect”),又或者collectgarbage(“step”))进行显式回收。

**

## 【使用LUA开发游戏,发现内存耗费成倍增长】

**

内存随着时间成倍增加,这个感觉应该是和堆栈分配有关系,但是看我们LUA框架代码,大部分用到LUA地方都有进行释放了呀。。。

挨个对照COCOS2D-X提供的LUA框架和我们的LUA框架,发现在一般的方法,比如执行字符串,执行文件,等等ExecuteString,ExecuteScriptFile,ExecuteGlobalFunction函数写法都一样,于是范围缩小到我们自己写的几个函数里面。我们自己封装的执行对话框内部函数ExecuteTableFunction,GetTableFuntion等几个,仔细阅读代码后,终于发现问题了:

1)堆栈用完没有及时恢复

2)没有及时使用垃圾回收
解决方案

1)在函数异常返回或者正常处理返回时,堆栈要进行恢复:

lua_pop(L, 1);

// 恢复之前的栈顶位置

lua_settop(L, 0);

2)在调用lua_pcall()时,要调用lua_gc(L, LUA_GCCOLLECT, 0);进行垃圾回收;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值