--[[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
|