对象池(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
实战:子弹/伤害数字对象池:
实战:子弹/伤害数字对象池
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 快了快了,马上就能用VV了 快了快了,马上就能用VV了
页:
[1]