加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Lua的内存监测和回收

发布时间:2020-12-14 22:01:12 所属栏目:大数据 来源:网络整理
导读:Lua内存是自动收集的,?这点跟Java类似,?不被任何对象或全局变量引用的数据,将被首先标记为回收,不需要开发者做任何事情.但是,正如Java也会有内存泄露一样,Lua也会有,?只不过,跟C++的不同,它是由于代码执行所装载的资源,并没有被彻底销毁而导致,其中,最

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

?

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

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

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

function test1()
  collectgarbage("collect") --清理之前的垃圾
  local c1=collectgarbage("count")
  print()
  print("最起始,Lua使用内存为:"..c1.."K")
  print()
  colen={} --声明一个本地变量
  print("现在,声明5000个数组,并加到colen中....")
  print()
  for i=1,5000 do
    table.insert(colen,i) --插入元素
  end
  local c2=collectgarbage("count")
  print("现在Lua使用内存为:"..c2.."K")
  print()

end

运行结果如下:


?这里看到,?被local?声明的colen加了5000数组,test1调用后,?内存增加了大概128K(156K-28K).
现在,我们来做内存回收(调用mem函数,?代码如下):
function men()
 print()
 print("调用GC收集")
 print()
 collectgarbage("collect")
 local c1=collectgarbage("count")
 print("收集后,当前Lua使用的内存为:"..c1)
 print()
end

?运行结果:


(?为了保证内存的稳定,以上注意mem被调用了多次,?再第2次,?可以看到内存开始下降,?最后,大概在25618K稳定下来)
?好了,? 也就是说,函数test1的执行,并没有产生无法回收的内存,没有泄露出现.

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

function test2()
  collectgarbage("collect") --清理之前的垃圾
  local c1=collectgarbage("count")
  print()
  print("最起始,Lua使用内存为:"..c1.."K")
  print()
  colen={} --声明一个本地变量
  print("现在,声明5000个数组,并加到colen中....")
  print()
  for i=1,i) --插入元素
  end
  local c2=collectgarbage("count")
  print("现在Lua使用内存为:"..c2.."K")
  print()

end


结果:


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


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

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

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

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

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

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

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读