查看: 64|回复: 4

[Lua] VVM2服务端Lua内存泄漏:常见原因 + 自制检测工具

[复制链接]

46

主题

42

回帖

1212

积分

金牌会员

积分
1212
发表于 2026-6-5 00:11:21 | 显示全部楼层 |阅读模式
-- MemoryWatcher.lua
-- 定期采样内存,输出增长趋势,帮助定位泄漏点

local M = {}
local _snapshots = {}
local _trackers  = {}  -- 追踪特定表的大小变化

-- 采样一次(依赖引擎提供的内存查询接口)
function M.snapshot(label)
    local kb = collectgarbage("count")
    table.insert(_snapshots, {
        label = label or ("t" .. #_snapshots + 1),
        kb    = kb,
        time  = os.time(),
    })
    return kb
end

-- 打印增长报告
function M.report()
    if #_snapshots < 2 then
        print("[MemWatcher] 至少需要2次采样")
        return
    end
    local base = _snapshots[1]
    print(string.format("%-12s %8s %8s", "标签", "KB", "增长KB"))
    print(string.rep("-", 32))
    for _, s in ipairs(_snapshots) do
        print(string.format("%-12s %8.1f %+8.1f",
            s.label, s.kb, s.kb - base.kb))
    end
end

-- 追踪一个全局表的元素数量变化(找哪个表在无限增长)
function M.track(name, tbl)
    _trackers[name] = tbl
end

function M.checkTrackers()
    for name, tbl in pairs(_trackers) do
        local count = 0
        for _ in pairs(tbl) do count = count + 1 end
        print(string.format("[Track] %-20s 元素数: %d", name, count))
    end
end
配合定时器使用:

local MW = require("MemoryWatcher")

-- 追踪可疑的全局表
MW.track("PlayerCache",   PlayerCache)
MW.track("EventListeners", _listeners)

-- 每5分钟采样一次
local tick = 0
SetTimer(300 * 1000, function()
    tick = tick + 1
    MW.snapshot("t" .. tick .. "(" .. tick*5 .. "min)")
    MW.checkTrackers()

    if tick % 6 == 0 then  -- 每30分钟打印一次报告
        MW.report()
    end
end)

-- ❌ 泄漏1:事件监听器只注册不注销
-- 玩家下线后 listener 仍挂在全局表里
EventBus.on("player_die", function() ... end)  -- 没有对应的 off

-- ❌ 泄漏2:用玩家名做key缓存,玩家下线后不清理
_cache[playerName] = bigObject  -- 永远不删

-- ❌ 泄漏3:闭包意外捕获大对象
local bigTable = loadAllItems()  -- 几千条数据
SetTimer(1000, function()
    -- 只用了 bigTable 的一个字段,但整个 bigTable 被闭包持有
    print(bigTable.count)
end)

-- ✅ 正确做法:只捕获需要的值
local count = loadAllItems().count
SetTimer(1000, function() print(count) end)

return M


1

主题

228

回帖

1585

积分

金牌会员

积分
1585
发表于 2026-6-5 10:11:04 | 显示全部楼层
多发点ai写的东西

25

主题

89

回帖

1323

积分

金牌会员

积分
1323
发表于 2026-6-5 10:25:24 | 显示全部楼层
快了快了,马上就能用VV了

46

主题

42

回帖

1212

积分

金牌会员

积分
1212
楼主 发表于 2026-6-5 13:45:34 | 显示全部楼层

快了快了,马上就能用VV了

25

主题

57

回帖

1393

积分

金牌会员

积分
1393
发表于 2026-6-5 19:23:06 | 显示全部楼层
快了快了,马上就能用VV了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表