Lua的内存监测和回收

 

      Lua 内存是自动收集的 这点跟 Java 类似 不被任何对象或全局变量引用的数据,将被首先标记为回收 , 不需要开发者做任何事情 . 但是,正如 Java 也会有内存泄露一样 , Lua 也会有 只不过 , C++ 的不同,它是由于代码执行所装载的资源,并没有被彻底销毁而导致 , 其中,最臭名昭著的就是不小心把局部变量声明成了全局变量 ( 忘了加 local 修饰符 )。  类似这样造成的内存泄露 跟任何其他语言的内存泄露一样,容易产生,却难以察觉 给开发的应用带来潜在的很大隐患 .

那么有没有一些有效的解决办法来解决这个这个隐患呢答案就是collectgarbage. collectgarbage就是开放给Lua开发人员用于监听Lua的内存使用情况(collectgarbage("count")), 同时,它还提供了collectgarbage("collect"),允许在适当的时候进行显式的回收.

现在,通过测试代码来看看,如何玩转collectgarbage.

首先,为了有明显的对比, 先来看没有产生泄露的情况运行以下的test1(代码如下):


 

运行结果如下:



  这里看到 , local 声明的 colen 加了 5000 数组 , test1 调用后 , 内存增加了大概 300K(25906K-25620K).
现在,我们来做内存回收 ( 调用 mem 函数 , 代码如下 ):


 运行结果:

为了保证内存的稳定 , 以上注意 mem 被调用了多次 , 再第 2 , 可以看到内存开始下降 , 最后 , 大概在 25618K 稳定下来)
  好了 , 从最初的 25620K, 到回收后的 25618K, 两者并没有发生变化 (还少了2K,嘿嘿, 这应该是 误差了 ), 也就是说 , 函数 test1 的执行,并没有产生无法回收的内存,没有泄露出现 .

好了,现在运行有泄露的test2(代码如下), test2test1相比,只有一处不同:就是colen被误声明为全局:


结果:

  也就是说 , 内存也在 25906K, test1 几乎是相等 , 好了,现在再调用回收 (mem) 函数 , 产生结果如下

  为了保证函数回收被执行,这次,总共调用了 7 mem 函数(看以上打印行数) , 那么,从上面的结果我们看 , 很不幸 , 从第 1 次,到最后第 7 , 内存都还是稳定在 25905K 左右 , 也就是说 , 跟调用 test2 前相比,即使 Lua 进行了内存回收 , 内存却不会将下来 看来 , 300K(25906K-25620K) 内存 , 由于已放到了全局函数中,是永远没有机会被回收到了 !

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

1.       针对会产生泄露的函数,先调用collectgarbage("count"),取得最初的内存使用

2.       函数调用后, collectgarbage("collect")进行收集, 并使用collectgarbage("count")再取得当前内存, 最后记录两次的使用差

3.       test1的收集可看到, collectgarbage("collect")被调用,并不保证一次成功, 所以, 大可以调用多次

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

1.       当然是代码实现不出现泄露, (废话*&%$()

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

猜你喜欢

转载自colen.iteye.com/blog/578146
今日推荐