您的位置:首页 > 编程语言 > Lua

Lua内存泄露情况举例

2016-05-30 11:36 363 查看

1、在多次刷新的情况下不停的 新建table;

如 Update()是一个不停被回调的函数,那么在Update里,

function Update()

local t = {};--创建表,内存泄露,游戏常见到

end

会产生很多消耗。

2、长字符串,虽然Lua虚拟机不会显示这块内存,但任务管理器还是会产生巨大的消耗。

如:

local s = "", 

for i = 1, 1000000, 1 do

  s = s .. i --字符串消耗大量内存

end

3、占位符,三个点作为参数的空函数,里面不执行占位符

function EventTouch(...)

end

该函数的调用会产生内存泄露,泄露规模和引入参数的个数有关,如EventTouch(t, x, y),调用一次和产生一个{t, x, y}的规模一样。处理办法:限定参数个数,调用占位符参数,或者去掉参数。

4、Lua面向对象产生内存泄露

看看构造函数:

Father = {};

function Father:New(o)

    local child = o or {};--分析:这里生成或者引用一个表,已经产生一次内存泄露;

    setmetatable(child, {__index = self});--这里因为保护父类,又增加一个表,泄露;

    return child;

end

常规省事的做法:

Father = {}

Father.__index = Father

function Father:New(o)

    local child = o or {}

    setmetatable(child, Father)--不用保护父类,减少不必要的内存消耗

    return child

end

5、创建坐标点(向量)产生内存泄露:

很多人因为C++,Java写多了,对于坐标一般都这样来

Object.Point = {X = 0, Y = 0}

这样写很蠢,因为又产生泄露,而且索引Object.Point.X 是相当慢的,用这种方法写出来的粒子比乌龟还慢。

比较好的写法:

Object.PointX = 0

Object.PointY = 0

很多人无法接受这样的写法,但事实上,这种写法最经济。如果你尝试讲一个算法从C改写为Lua,不妨尝试上述写法。

6、Lua调控userdata

如果userdata创建本身就产生大量内存消耗,这个要注意用日志前后打印出来

7、创建树:

树也会产生大量的表,最聪明的做法就是把树状表改为table,用一个表就可以直接表示完所有的树。

树是可以改写为广义表的,因此可以尝试用一个表,或者字符串序列表示树!

Node = {

   childs = {n1, n2, ...}

}

8、创建图:

类似上面,封闭图,开放图也可以改写为一个表。内存得到控制。

9、池管理出错了!

Pool = {}

Pool.ActiveObjects = {}

Pool.InactiveObjects = {}

function Pool:GetOjbect()

    --if Pool.InactiveOjbects 里还有死对象 then

        --激活第一个死对象,并挪到Pool.ActiveObjects里。

    --否则

        --从生成一个对象,放到Pool.ActiveObjects里

    --返回该对象的地址出来

end

Object = {}

Object.__index = Object

function Object:New(o)

    local obj = o or Pool:GetObject() 所有的对象均从Pool.ActiveObjects里获取,降低内存创建消耗

    setmetatable(obj, Ojbect)

    return obj

end

function Object:Delete()

    --

    Pool:Collect(self)

end

10、多维数组 内存泄露

其实多维也可以用一维表示

array = {

    {v11,v12,...,v1n},

    {v21,v22,...,v2n},

    ...

    {vm1,vm2,...,vmn},

}

这需要创建m个表;

改写如下:

array = {

    v11,v12,...,v1n,

    v21,v22,...,v2n,

    ...,

    vm1,vm2,...,vmn,

}

只要一张表!

11、闭包创建匿名函数泄露内存

function foo()

    return function() print("hello!") end --创建匿名函数,内存泄露

end

local helloFunc = foo()

helloFunc()

如果foo在回调过程里大量使用,那么会有产生大量泄露出来

比较好的办法,一次匿名,多次0泄露引用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: