|
|
发表于 2026-6-17 14:55:10
|
显示全部楼层
-- MemoryWatcher.lua 修复优化版
local M = {}
local _snapshots = {}
local _trackers = {} -- key:表名, value:{tbl=目标表, lastCount=上次元素数}
local _maxSnapShot = 200 -- 最多保留200条快照,防止无限膨胀
local _enable = true -- 监控总开关
-- 内部执行完整GC再采样,返回当前内存KB
local function getCleanMemKB()
collectgarbage("collect") -- 完整垃圾回收
return collectgarbage("count")
end
-- 采样一次
function M.snapshot(label)
if not _enable then return 0 end
local kb = getCleanMemKB()
local nowSec = os.time()
local idx = #_snapshots + 1
local autoLabel = string.format("t%d_%s", idx, os.date("%H:%M:%S", nowSec))
label = label or autoLabel
table.insert(_snapshots, {
label = label,
kb = kb,
time = nowSec,
clock = os.clock()
})
-- 超出上限自动清理旧快照
if #_snapshots > _maxSnapShot then
table.remove(_snapshots, 1)
end
return kb
end
-- 输出完整报告:相对初始基准 + 相邻间隔增量
function M.report()
if not _enable then return end
if #_snapshots < 2 then
print("[MemWatcher] 至少需要2次采样才能生成报告")
return
end
local base = _snapshots[1]
print("\n===== 内存增长报告 =====")
print(string.format("%-15s %8s %8s %8s %10s", "标签", "KB", "总增长KB", "间隔增长KB", "间隔秒"))
print(string.rep("-", 50))
local prev = base
for _, s in ipairs(_snapshots) do
local totalInc = s.kb - base.kb
local stepInc = s.kb - prev.kb
local diffSec = s.time - prev.time
print(string.format(
"%-15s %8.1f %+8.1f %+8.1f %10d",
s.label, s.kb, totalInc, stepInc, diffSec
))
prev = s
end
print("========================\n")
end
-- 追踪指定表,自动记录历史数量
function M.track(name, tbl)
if tbl == nil then
print(string.format("[MemWatcher] 追踪失败 %s:目标表为空", name))
return
end
-- 避免重复覆盖提示
if _trackers[name] then
print(string.format("[MemWatcher] 警告:覆盖已有追踪表 %s", name))
end
-- 不直接存原始表弱引用,降低常驻风险
local count = 0
for _ in pairs(tbl) do count = count + 1 end
_trackers[name] = {tbl = tbl, lastCount = count}
end
-- 检查所有追踪表,输出数量+变化差值
function M.checkTrackers()
if not _enable then return end
print("\n[MemTracker] 表元素监控:")
for name, info in pairs(_trackers) do
local tbl = info.tbl
local curr = 0
for _ in pairs(tbl) do curr = curr + 1 end
local diff = curr - info.lastCount
print(string.format(
" %-20s 当前数量:%6d 变化:%+6d",
name, curr, diff
))
info.lastCount = curr
end
print()
end
-- 控制接口:启停、清理数据
function M.setEnable(flag) _enable = flag end
function M.clearAll()
_snapshots = {}
_trackers = {}
end
return M |
|