tibaiwan1888 发表于 2026-6-5 00:00:46

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

-- 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
实战:子弹/伤害数字对象池:

tibaiwan1888 发表于 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

qq154886255 发表于 2026-6-5 10:13:55

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

jz9005 发表于 2026-6-6 00:33:58

快了快了,马上就能用VV了
页: [1]
查看完整版本: 对象池(ObjectPool)+ 弱引用表:解决高频创建对象的GC压力