--[[lua obj tool]] luaobj = luaobj or {} function luaobj.isobj(obj) local meta = getmetatable(obj) if meta ~= nil then return meta.__is_co_meta or false end return false end function luaobj.getid(obj) if luaobj.isobj(obj) then return obj._iid, obj._cid end return 0, 0 end function luaobj.getclasscountinfo( class_type ) local all_alloc_count = _in_obj_count_map[class_type] local not_call_del_count = 0 local total_live_count = 0 for k, v in pairs(_in_obj_ins_map[class_type]) do if not v._use_delete_method then not_call_del_count = not_call_del_count + 1 end total_live_count = total_live_count + 1 end return total_live_count, not_call_del_count, all_alloc_count end _snap_luaobj_map = snap_luaobj_map or {} function luaobj.memtool( action, extend ) local handle_content = action or "info" local save_file = extend or "console" local is_use_file = false if save_file ~= "console" then is_use_file = true end local open_write_func = function() local tmp_file = nil local out_func = print if is_use_file then tmp_file = io.open(save_file, "w+") if tmp_file ~= nil then out_func = function( ... ) tmp_file:write(...) end end end return tmp_file, out_func end local close_write_func = function(write_file) if write_file ~= nil then write_file:close() end end if handle_content == "info" then local tmp_file, out_func = open_write_func() -- -- print("_in_index_Count = ",_in_index_Count) local index = 0 -- for k,v in pairs(_in_ctype_map) do -- t = Split(v._source,"/") -- class_name = t[#t] -- class_name = string.gsub(class_name,".lua","") -- if class_name and LuaMemManager.Instance.agent_list[class_name] then -- print("not delete agent_list = ",class_name) -- index = index + 1 -- end -- end -- local class_name = "" -- local t = nil -- for class_name,v in pairs(LuaMemManager.Instance.agent_list) do -- if class_name and _in_ctype_map[_G[class_name]] then -- print("not delete agent_list = ",class_name) -- index = index + 1 -- end -- end -- print("index = ",index) -- local index = 0 -- -- for pro,v in pairs(_G) do -- -- if LuaMemManager.Instance.notPreLoadGame_table[pro] then -- -- print("_G pro=",pro) -- -- index = index + 1 -- -- end -- -- end -- -- print("对象总数:",index) -- for k,v in pairs(_in_ctype_map) do -- local total_live, not_del_count, all_alloc_count = luaobj.getclasscountinfo(v) -- -- if v._source then -- -- -- print(v._source) -- -- local t = Split(v._source,"/") -- -- local class_name = t[#t] -- -- class_name = string.gsub(class_name,".lua","") -- -- if LuaMemManager.Instance.notPreLoadGame_table[class_name] then -- if total_live > 10 then -- -- if string.find(v._source,"SingleServiceBossEnterView") then -- out_func(string.format("live num %4d, cid:%8d, not call del num:%4d, all alloc:%8d|src: %s[%d]\n", -- total_live, k, not_del_count, all_alloc_count, v._source, v._cline)) -- index = index + 1 -- end -- -- end -- -- end -- -- end -- end -- print("类对象总数:",index,"实例化对象总数:",_in_obj_ins_id) -- close_write_func(tmp_file) -- index = 0 for k,v in pairs(Config) do -- if _in_index_count_map[k] and _in_index_count_map[k] > 10 then -- if LuaMemManager.Instance.notPreLoadCfg_table[k] then print("~~~~~~~~配置属性:",k) index = index + 1 -- end -- end end print("配置总数:",index) elseif handle_content == "pmc" then local tmp_file, out_func = open_write_func() local index = 0 _test_baseclass_list = _test_baseclass_list or {} local test_vo = nil for k,v in pairs(_in_ctype_map) do test_vo = _test_baseclass_list[k] local total_live, not_del_count, all_alloc_count = luaobj.getclasscountinfo(v) if test_vo then total_live = total_live - test_vo.total_live not_del_count = not_del_count - test_vo.not_del_count all_alloc_count = all_alloc_count - test_vo.all_alloc_count test_vo["total_live"] = total_live + test_vo.total_live test_vo["not_del_count"] = not_del_count + test_vo.not_del_count test_vo["all_alloc_count"] = all_alloc_count + test_vo.all_alloc_count else test_vo = {} _test_baseclass_list[k] = test_vo test_vo["total_live"] = total_live test_vo["not_del_count"] = not_del_count test_vo["all_alloc_count"] = all_alloc_count end if total_live ~= 0 or not_del_count ~= 0 or all_alloc_count ~= 0 then out_func(string.format("此过程中创建的类对象src: %s[%d]增加了:%4d个,其中存活的 %2d个,没有调用deleteMe的:%2d个\n", v._source, v._cline,all_alloc_count,total_live, not_del_count)) index = index + 1 end end print("类对象总数:",index) index = 0 _test_config_list = _test_config_list or {} for k,v in pairs(Config) do if LuaMemManager.Instance.notPreLoadCfg_table[k] and _test_config_list[k] == nil then print("~~~~~~~~配置属性:",k) _test_config_list[k] = true index = index + 1 else _test_config_list[k] = nil end end print("配置总数:",index) elseif handle_content == "snap" then _snap_luaobj_map = {} for k,v in pairs(_in_ctype_map) do local total_live, not_del_count, all_alloc_count = luaobj.getclasscountinfo(v) _snap_luaobj_map[k] = total_live end print("Lua memory tools: handle snap action suc!") elseif handle_content == "diff" then local tmp_file, out_func = open_write_func() for k,v in pairs(_in_ctype_map) do local total_live, not_del_count, all_alloc_count = luaobj.getclasscountinfo(v) local old_live_num = _snap_luaobj_map[k] or 0 if old_live_num < total_live then out_func(string.format("add_num:%4d, cid:%8d | src: %s[%d]\n", total_live - old_live_num, k, v._source, v._cline)) end end close_write_func(tmp_file) print("Lua memory tools: handle diff action suc!") elseif handle_content == "search" then if extend ~= nil then for k,v in pairs(_in_ctype_map) do if string.find(v._source, extend) ~= nil then print(string.format("search class info: cid = %8d, source = %s[%d]\n", k, v._source, v._cline)) end end end print("Lua memory tools: handle search action suc!") elseif handle_content == "list" then if extend ~= nil then local val = tonumber(extend) local ctype = _in_ctype_map[val] if ctype ~= nil then for k, v in pairs(_in_obj_ins_map[ctype]) do print(string.format("list live obj: id = %8d, is_del = %d", k, v._use_delete_method and 1 or 0)) end end end else print("Lua memory tools: error args when call lua mem tool!") end end --[[lua debug tool]] luaobj_debug_tool = luaobj_debug_tool or {} function luaobj_debug_tool.is_lua_class_type( obj ) return obj.__is_cc_type or false end function luaobj_debug_tool.get_lua_class_type_vtable( obj ) local meta = getmetatable(obj) return meta.__index end function luaobj_debug_tool.detect_lua_obj_in_val( v, id, is_instance_id, path_desc, detect_list ) --print("now detect", v, path_desc) local type_name = type(v) if type_name == "table" then if not detect_list[v] then if luaobj.isobj(v) then local new_path_desc = path_desc .."[luaobj]" local obj_id, obj_cid = luaobj.getid(v) if is_instance_id then if obj_id == id then print("Find Obj Path", path_desc) end else if obj_cid == id then print("Find Obj Path", path_desc) end end local delegate_tbl = v --print("delegate table is:") --PrintTable(delegate_tbl) luaobj_debug_tool.search_obj_in_table(delegate_tbl, id, is_instance_id, new_path_desc, detect_list) detect_list[v] = true else luaobj_debug_tool.search_obj_in_table(v, id, is_instance_id, path_desc, detect_list) if luaobj_debug_tool.is_lua_class_type(v) then luaobj_debug_tool.search_obj_in_table(luaobj_debug_tool.get_lua_class_type_vtable(v), id, is_instance_id, path_desc, detect_list) end end end elseif type_name == "function" then detect_list[v] = true local func_path_desc = path_desc .. "[function]" local up_index = 1 while true do local up_val_name, up_val = debug.getupvalue(v, up_index) if up_val == nil then break end local new_path_desc = func_path_desc .. "->[up(" .. up_val_name .. ")]" --print("up value detect", new_path_desc) luaobj_debug_tool.detect_lua_obj_in_val(up_val, id, is_instance_id, new_path_desc, detect_list) up_index = up_index + 1 end end end function luaobj_debug_tool.search_obj_in_table( tbl, id, is_instance_id, path_desc, detect_list) --print("now detect", tbl, path_desc) -- body if detect_list[tbl] then return end detect_list[tbl] = true for k, v in pairs(tbl) do --io.stderr:write(tostring(k)) local new_path_desc = path_desc .. "->" .. tostring(k) luaobj_debug_tool.detect_lua_obj_in_val(v, id, is_instance_id, new_path_desc, detect_list) new_path_desc = path_desc .. "->[key]" .. tostring(k) luaobj_debug_tool.detect_lua_obj_in_val(k, id, is_instance_id, new_path_desc, detect_list) end end