在进一步优化公司项目的时候发现,我们项目在开始游戏进入主城的时候lua占用内存是45.0M,C#占用内存9.6M,而随着多次游戏再返回主城之后,lua的内存占用有时候能高达140M(多了100M),很显然是发生了内存泄露,这里介绍一个检查内存泄露的工具供大家使用,我加了一点注释和修改更方便理解
--这是lua代码 --初始化内存泄露监视表 function initMemoryTable() t_memoryTable = {} setmetatable(t_memoryTable, {__mode = "k"}) end --把一个对象放入内存监视表 function putOneObjeatInMemoryTable( x_someThing,x_id ) if x_someThing ~= nil then t_memoryTable[x_someThing] = x_id; end end --显示所有没有被释放的对象(仅判断在内存监视表中的对象) function showTheMrmoryTable() local n_count = 0; for k,v in pairs(t_memoryTable) do n_count =n_count + 1; warn("id: "..tostring(v).." obj: "..tostring(k)); _G.findObjectInGlobal(k) end end local findedObjMap = nil --递归地从某位置寻找某一个对象,并自动从其子节点继续寻找 function _G.findObject(obj, findDest) if findDest == nil then return false end if findedObjMap[findDest] ~= nil then return false end findedObjMap[findDest] = true local destType = type(findDest) if destType == "table" then if findDest == _G.CMemoryDebug then return false end for key, value in pairs(findDest) do if key == obj then warn("Finded Object: key == obj") return true end if value == obj then warn("Finded Object key:["..tostring(key).."]") return true end if findObject(obj, key) == true then warn("table key") return true end if findObject(obj, value) == true then warn("key:["..tostring(key).."]") return true end end elseif destType == "function" then local uvIndex = 1 while true do local name, value = debug.getupvalue(findDest, uvIndex) if name == nil then break end if findObject(obj, value) == true then warn("upvalue name:["..tostring(name).."]") return true end uvIndex = uvIndex + 1 end end return false end --从G表中寻找某一个对象,并打印其位置 function _G.findObjectInGlobal(obj) findedObjMap = {} setmetatable(findedObjMap, {__mode = "k"}) if _G.findObject(obj, _G) == true then warn("in _G"); end end
这个工具的原理 参考文章