lua对象池管理工具剖析

lua对象池管理工具剖析

一个高效的对象池实现,通过对象复用来减少内存分配和垃圾回收压力,特别适合频繁创建销毁对象的场景

源码

lua 复制代码
-- object pool, from: https://github.com/treamology/pool.lua

local type, pairs, table, setmetatable = type, pairs, table, setmetatable 
local pool = {}
local poolmt = {__index = pool}

function pool.create(newObject, poolSize, maxPoolSize)
    if type(newObject) ~= "function" then
        return nil
    end

    poolSize = poolSize or 16
    maxPoolSize = (maxPoolSize and maxPoolSize >= poolSize) and maxPoolSize or 2 * poolSize
    local freeObjects = {}
    for _ = 1, poolSize do
        table.insert(freeObjects, newObject())
    end

    return setmetatable({
            freeObjects = freeObjects,
            newObject = newObject,
            maxPoolSize = maxPoolSize
        },
        poolmt
    )
end

function pool:obtain()
    return #self.freeObjects == 0 and self.newObject() or table.remove(self.freeObjects)
end

function pool:free(obj, ...)
    if not obj then
        return false
    end
    if #self.freeObjects < self.maxPoolSize then
        table.insert(self.freeObjects, obj)
    end

    if obj.reset then obj.reset(obj, ...) end
    return true
end

function pool:clear()
    for k in pairs(self.freeObjects) do
        self.freeObjects[k] = nil
    end
end

return pool

对象池创建函数

lua 复制代码
function pool.create(newObject, poolSize, maxPoolSize)
    -- 参数验证:必须提供对象构造函数
    if type(newObject) ~= "function" then
        return nil
    end

    -- 参数默认值设置
    poolSize = poolSize or 16
    maxPoolSize = (maxPoolSize and maxPoolSize >= poolSize) and maxPoolSize or 2 * poolSize
    
    -- 预分配对象池
    local freeObjects = {}
    for _ = 1, poolSize do
        table.insert(freeObjects, newObject())
    end

    -- 返回池实例
    return setmetatable({
            freeObjects = freeObjects,
            newObject = newObject,
            maxPoolSize = maxPoolSize
        },
        poolmt
    )
end

对象获取机制

lua 复制代码
function pool:obtain()
    return #self.freeObjects == 0 and self.newObject() or table.remove(self.freeObjects)
end

执行逻辑:

对象回收机制

lua 复制代码
function pool:free(obj, ...)
    if not obj then
        return false
    end
    -- 检查池容量,避免无限增长
    if #self.freeObjects < self.maxPoolSize then
        table.insert(self.freeObjects, obj)
    end

    -- 调用对象的reset方法进行清理
    if obj.reset then obj.reset(obj, ...) end
    return true
end

池清理功能

lua 复制代码
function pool:clear()
    for k in pairs(self.freeObjects) do
        self.freeObjects[k] = nil
    end
end

设计模式分析

1. 对象池模式

lua 复制代码
-- 使用示例
local function createConnection()
    return { 
        id = math.random(1000),
        connected = false,
        reset = function(self)
            self.connected = false
        end
    }
end

local connectionPool = pool.create(createConnection, 10, 50)

2. 享元模式

通过对象复用,减少相似对象的创建开销

内存管理策略

策略 实现方式 优势
预分配 初始化时创建固定数量对象 减少运行时分配
动态扩展 池空时自动创建新对象 避免阻塞
容量限制 maxPoolSize控制内存上限 防止内存泄漏

垃圾回收优化

lua 复制代码
-- 传统方式:频繁创建销毁
for i = 1, 1000 do
    local obj = createObject()  -- 触发GC
    use(obj)
    -- obj被销毁,GC压力大
end

-- 对象池方式:复用对象
for i = 1, 1000 do
    local obj = pool:obtain()   -- 从池中获取
    use(obj)
    pool:free(obj)              -- 放回池中,无GC压力
end

使用场景分析

1. 网络连接管理

lua 复制代码
local socketPool = pool.create(function()
    return {
        fd = nil,
        status = "closed",
        reset = function(self)
            if self.fd then
                self:close()
            end
            self.status = "closed"
        end,
        connect = function(self, host, port)
            -- 连接逻辑
        end
    }
end, 20, 100)

2. 游戏对象管理

lua 复制代码
local bulletPool = pool.create(function()
    return {
        x = 0, y = 0, 
        velocity = 100,
        active = false,
        reset = function(self)
            self.x, self.y = 0, 0
            self.active = false
        end
    }
end, 50, 200)

3. 数据库连接池

lua 复制代码
local dbPool = pool.create(function()
    local conn = mysql.connect(config)
    return {
        conn = conn,
        reset = function(self)
            -- 重置连接状态
            self.conn:ping()  -- 保持连接活跃
        end
    }
end, 5, 20)

与直接创建方案的对比

方面 对象池 直接创建
内存分配 预分配+复用 每次新建
GC压力 极小 频繁触发
初始化成本 一次性 每次都有
灵活性 需要reset逻辑 无需特殊处理
相关推荐
久菜盒子工作室8 分钟前
时寒冰:第五次产业大转移与未来30年国运:在“双向挤压”中实现惊险一跃
人工智能·学习
草履虫君21 分钟前
VMware 虚拟机网络性能优化指南:从 11 秒到 4 秒的完整调优实践
服务器·网络·经验分享·性能优化
We་ct21 分钟前
深度剖析浏览器跨域问题
开发语言·前端·浏览器·跨域·cors·同源·浏览器跨域
日取其半万世不竭25 分钟前
LVM 逻辑卷管理:不停机扩容磁盘的正确方式
运维·服务器
skywalk816330 分钟前
在考虑双轨制,即在中文语法的基础上,加上数学公式的支持,这样像很多计算将更加简单方便,就像现在的小学数学课本里面一样,比如:定x=2*x + 1
开发语言
小书房33 分钟前
Kotlin的by
android·开发语言·kotlin·委托·by
就叫飞六吧1 小时前
QT写一个桌面程序exe并动态打包基本流程(c++)
开发语言·c++
threelab1 小时前
Three.js 代码云效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能
V搜xhliang02461 小时前
OpenClaw科研全场景用法:从文献到实验室的完整自动化方案
运维·开发语言·人工智能·python·算法·microsoft·自动化
kaikaile19951 小时前
风、浪、流环境模型的船舶三自由度(纵荡、横荡、艏摇)运动仿真MATLAB
开发语言·人工智能·matlab