Files
Endfield-Data/LuaScripts/Common/Core/LuaObjectMemoryLeakChecker.lua
2025-12-02 20:37:18 +07:00

117 lines
3.7 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
LuaObjectMemoryLeakChecker = HL.Class('LuaObjectMemoryLeakChecker')
local GCMeta = {}
LuaObjectMemoryLeakChecker.destoryObjects = HL.Field(HL.Table)
LuaObjectMemoryLeakChecker.isGcEnd = HL.Field(HL.Boolean) << false
LuaObjectMemoryLeakChecker.coCheker = HL.Field(HL.Thread)
LuaObjectMemoryLeakChecker.LuaObjectMemoryLeakChecker = HL.Constructor() << function(self)
self.destoryObjects = {}
setmetatable(self.destoryObjects, {__mode = "k"})
end
LuaObjectMemoryLeakChecker.checkRegisterGC = HL.Method() << function(self)
while true do
coroutine.wait(2,self.coCheker)
if self.isGcEnd then
self:_DetectLuaObject()
self:_ReStartChecker()
end
end
end
LuaObjectMemoryLeakChecker._ReStartChecker = HL.Method()<< function(self)
if self.coCheker then
CoroutineManager:ClearCoroutine(self.coCheker)
self.coCheker = nil
end
self:_createGCListenerTable()
end
LuaObjectMemoryLeakChecker._createGCListenerTable = HL.Method()<< function(self)
if self.coCheker ~= nil then
return
end
local coCheker = CoroutineManager:StartCoroutine(function()
LuaObjectMemoryLeakChecker.checkRegisterGC(self)
end)
local instance = {}
self.isGcEnd = false
GCMeta.__gc = function()
if(coCheker == self.coCheker) then
self.isGcEnd = true
end
end
setmetatable(instance,GCMeta)
self.coCheker = coCheker
end
LuaObjectMemoryLeakChecker.AddDetectLuaObject = HL.Method(HL.Any) << function(self, object)
local GetUserdataAddr = nil
local address = GetUserdataAddr ~= nil and tostring(GetUserdataAddr(object)) or tostring(object)
local typeinfo = type(object) == "userdata" and HyperLua.GetTypeName(object) or type(object)
local time = DateTimeUtils.GetCurrentTimestampByMilliseconds()
local info = "memory leak address:"..address.." type "..typeinfo.." start time: "..time
self.destoryObjects[object] =
{
[1] = time,
[2] = info,
[3] = address
}
self:_ReStartChecker()
end
LuaObjectMemoryLeakChecker.RemoveDetectLuaObject = HL.Method(HL.Any) << function(self, obj)
self.destoryObjects[obj] = nil
end
LuaObjectMemoryLeakChecker._DetectLuaObject = HL.Method() << function(self)
local curTime = DateTimeUtils.GetCurrentTimestampByMilliseconds()
logger.warn("LuaObjectMemoryLeakChecker finish")
for object, infos in pairs(self.destoryObjects) do
if object ~= nil then
local time = curTime - infos[1]
logger.error(ELogChannel.UI, infos[2].." duration time:"..time)
local mri = require ("Debug/MemoryReferenceInfo")
mri.m_cConfig.m_bAllMemoryRefFileAddTime = false
mri.m_cConfig.m_bSingleMemoryRefFileAddTime = false
mri.m_cConfig.m_bComparedMemoryRefFileAddTime = false
end
end
end
LuaObjectMemoryLeakChecker.DumpAllLeakObject = HL.Method() << function(self)
collectgarbage("collect")
collectgarbage("collect")
local curTime = DateTimeUtils.GetCurrentTimestampByMilliseconds()
local fireName = CS.Beyond.VFS.UnityFileLoaderHelper.persistentDataPath.."/".."lua_memory_leak_dump_file_"..curTime..".txt"
logger.error(ELogChannel.UI, "dump lua file "..fireName)
local mri = require ("Debug/MemoryReferenceInfo")
mri.m_cConfig.m_bAllMemoryRefFileAddTime = false
mri.m_cConfig.m_bSingleMemoryRefFileAddTime = false
mri.m_cConfig.m_bComparedMemoryRefFileAddTime = false
for object, infos in pairs(self.destoryObjects) do
if object ~= nil then
mri.m_cMethods.DumpMemorySnapshotSingleObject(fireName,"", -1, infos[3], object)
end
end
end
HL.Commit(LuaObjectMemoryLeakChecker)
return LuaObjectMemoryLeakChecker