当前位置: 首页 > 工具软件 > LuaPerfect > 使用案例 >

Lua的内存泄露问题

范峰
2023-12-01

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,每次执行完,内存大小还是不断增加,为什么呢,我再想想吧

 类似资料: