查看: 53|回复: 3

[Lua] 对象池(ObjectPool)+ 弱引用表:解决高频创建对象的GC压力

[复制链接]

46

主题

42

回帖

1212

积分

金牌会员

积分
1212
发表于 2026-6-5 00:00:46 | 显示全部楼层 |阅读模式
-- ObjectPool.lua
-- 复用对象而不是频繁创建销毁,减少GC暂停

local ObjectPool = {}
ObjectPool.__index = ObjectPool

function ObjectPool.new(factory, reset)
    return setmetatable({
        _factory = factory,  -- 创建新对象的函数
        _reset   = reset,    -- 归还时重置对象的函数
        _pool    = setmetatable({}, { __mode = "v" }),  -- 弱引用,GC可回收
        _size    = 0,
    }, ObjectPool)
end

-- 借出对象
function ObjectPool:acquire()
    local obj = table.remove(self._pool)
    if obj then
        return obj
    end
    self._size = self._size + 1
    return self._factory()
end

-- 归还对象
function ObjectPool:release(obj)
    if self._reset then self._reset(obj) end
    table.insert(self._pool, obj)
end

function ObjectPool:poolSize() return #self._pool end
function ObjectPool:totalCreated() return self._size end

return ObjectPool
实战:子弹/伤害数字对象池:

46

主题

42

回帖

1212

积分

金牌会员

积分
1212
楼主 发表于 2026-6-5 00:01:39 | 显示全部楼层
实战:子弹/伤害数字对象池
local ObjectPool = require("ObjectPool")

-- 伤害飘字对象池
local DamageTextPool = ObjectPool.new(
    function()
        -- 创建一个伤害显示对象
        return { visible = false, value = 0, x = 0, y = 0, timer = 0 }
    end,
    function(obj)
        -- 归还时清空状态
        obj.visible = false
        obj.value   = 0
        obj.timer   = 0
    end
)

function ShowDamage(x, y, value)
    local txt = DamageTextPool:acquire()
    txt.x, txt.y, txt.value, txt.visible = x, y, value, true

    SetTimer(1500, function()
        DamageTextPool:release(txt)  -- 1.5秒后归还
    end)
end

-- 高频调用不再频繁分配内存
for i = 1, 100 do
    ShowDamage(math.random(0,1000), math.random(0,1000), math.random(1, 9999))
end

print("总创建对象数: " .. DamageTextPool:totalCreated())  -- 远小于100

1

主题

228

回帖

1585

积分

金牌会员

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

25

主题

89

回帖

1323

积分

金牌会员

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

本版积分规则

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