Lua内存泄漏
lua垃圾回收机制
- lua的GC使用 Mark And Sweep 标记清除算法
- 该算法设计了三种颜色标记对象(如树遍历)
- white 未标记(没有被使用过)
- gray 已标记、但关联节点未标记
- black 已标记、且与之关联的节点都扫描标记了
- 算法过程:Mark阶段:先将内存中所有对象扫描并标记。Sweep阶段:将所有未标记(white)的对象释放
内存泄漏形式 (持续更新中)
1.全局变量
- 因疏忽写出的全局变量,会一直保存在内存中,实际上没有再用到的,但内存一直被占用
2.匿名函数
- lua中的匿名函数在运行时的垃圾回收不会被释放内存,而普通函数会被释放内存
function Sleep(n)
os.execute("sleep " .. n)
end
a = {}
function updateDt(_func)
for i = 1, 10 do
Sleep(0.1)
_func(i)
end
end
function main()
print("TEST START ------------------------------------------")
print("now,Lua内存为:",collectgarbage("count"))
collectgarbage()
-- 例子A
updateDt(function (count)
a[count] = {}
a[count].a = {}
a[count].b = {}
a[count].c = {}
a[count].d = {}
a[count].e = {}
a[count].f = {}
a[count].g = {}
a[count].h = {}
print("now [" .. count .. "],Lua内存为:",collectgarbage("count"))
collectgarbage()
end)
-- 例子B
local function _update(count)
a[count + 10] = {}
a[count + 10].a = {}
a[count + 10].b = {}
a[count + 10].c = {}
a[count + 10].d = {}
a[count + 10].e = {}
a[count + 10].f = {}
a[count + 10].g = {}
a[count + 10].h = {}
print("now [" .. count .. "],Lua内存为:",collectgarbage("count"))
collectgarbage()
end
updateDt(_update)
print("now,Lua内存为:",collectgarbage("count"))
print("TEST END ------------------------------------------")
end
main()
TEST START ------------------------------------------
now,Lua鍐呭瓨涓? 28.71484375
now [1],Lua鍐呭瓨涓? 28.3271484375
now [2],Lua鍐呭瓨涓? 28.6396484375
now [3],Lua鍐呭瓨涓? 29.4130859375
now [4],Lua鍐呭瓨涓? 30.1552734375
now [5],Lua鍐呭瓨涓? 30.9599609375
now [6],Lua鍐呭瓨涓? 31.7021484375
now [7],Lua鍐呭瓨涓? 32.4443359375
now [8],Lua鍐呭瓨涓? 33.1865234375
now [9],Lua鍐呭瓨涓? 34.0537109375
now [10],Lua鍐呭瓨涓? 34.7978515625
now [1],Lua鍐呭瓨涓? 35.5771484375
now [2],Lua鍐呭瓨涓? 36.2802734375
now [3],Lua鍐呭瓨涓? 37.0224609375
now [4],Lua鍐呭瓨涓? 37.7646484375
now [5],Lua鍐呭瓨涓? 38.5068359375
now [6],Lua鍐呭瓨涓? 39.2490234375
now [7],Lua鍐呭瓨涓? 40.2412109375
now [8],Lua鍐呭瓨涓? 40.9833984375
now [9],Lua鍐呭瓨涓? 41.7255859375
now [10],Lua鍐呭瓨涓? 42.4697265625
now,Lua鍐呭瓨涓? 42.3369140625
TEST END ------------------------------------------
- 可以看到,例子A在匿名函数中每次执行垃圾回收操作后,内存大小还是不断增加
- 而例子B,每次执行完,内存大小还是不断增加,为什么呢,我再想想吧