CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
进阶实战游戏功能996引擎

Lua+弱表:GC回收不扫弱引用

2026-09-29 12:45 作者:996 技术组 996引擎Lua教程传奇脚本进阶实战游戏功能996引擎

【语法算法】

弱表的GC规则就这一行:

lua
setmetatable(cache, { __mode = "v" })

__mode = "v" 表示值的弱引用——GC 扫描时不会把弱表里的值算作活跃对象,如果值没有其他强引用,GC 直接回收,表里的键值对自动消失。今天拆开。

一、强引用、弱引用、GC 三段

弱表的三段。强引用:普通的表赋值 t[k] = v 创建的是强引用——只要 t 存在,v 就不会被 GC 回收,哪怕代码里再也没人用它。弱引用:__mode = "v" 的表里,值不影响 GC 判定——只有键有强引用时值才存活,键没有强引用了键值对自动消失。GC:Lua 的 GC 是增量三色标记——从根对象出发标记所有可达对象——弱表里的值如果只被弱表引用,标记阶段不会标记它,清扫阶段直接回收。三段连起来:弱表玩的是"缓存对象的自动过期"——不需要手动清理,GC 帮你干。

mermaid
graph TD
    A[GC根对象] --> B[全局表]
    A --> C[当前栈]
    B -->|强引用| D[缓存表 cache]
    D -->|弱引用-值| E[对象1]
    D -->|弱引用-值| F[对象2]
    E -->|无其他引用| G[GC回收]
    F -->|有其他引用| H[存活]

二、缓存表的正确写法

lua
local cache = setmetatable({}, { __mode = "v" })

local function getCached(key, factory)
    local v = cache[key]
    if v == nil then
        v = factory()
        cache[key] = v
    end
    return v
end

local tex1 = getCached("fire_tex", function()
    return loadTexture("fire.png")
end)

tex1 持有返回值的强引用——只要 tex1 还在作用域里,缓存就不会被 GC 回收——tex1 离开作用域后,如果缓存表也没有其他强引用指向这个值,GC 下次运行时自动回收。

三、弱键和弱值的分界线

__mode 有三种取值:"k" 键弱引用、"v" 值弱引用、"kv" 键值都弱引用。弱键适合"对象属性附加表"——以对象为键、附加数据为值,对象被回收后附加数据自动消失。弱值适合"缓存表"——以字符串为键、缓存对象为值,对象没有其他引用了缓存自动清空。两者的分界线就一句话:谁的生命周期由外部决定就用谁做弱引用。最后一条纪律:弱表里不要存布尔值和数字——GC 不会回收这些基础类型,弱引用对它们无效——弱表里只存表、函数、userdata 这些"真正的对象"。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

进阶实战游戏功能

影锁:影锁绑你绑它,锁期拼刀

【游戏功能】 控制技能的镜像问题是:锁住了怪,自己是不是也闲着?影锁把这道两难摆上台面:影锁四秒,它动不了、你也动不了——它…

2026-10-01 10:00 996 技术组
进阶实战游戏功能

震魂:震魂入体叠加出招自损

【游戏功能】 打断为什么只有"清读条"一种?震魂偏要反过来——不清招、不断势,打在它读条半途的那一劲顺着招震进腑——中劲十秒…

2026-10-01 10:00 996 技术组
进阶实战游戏功能

蜂王:喂小怪蜂王进化,三阶蜂王蜇翻全场

【游戏功能】 蜂群为什么总是一只一只出?蜂王偏要让它们进化:放一只蜂王出来,杀掉小怪喂它——喂三只升一阶,三阶蜂王的毒刺一秒…

2026-10-01 10:00 996 技术组
进阶实战游戏功能

血刃:每刀扣血换吸血,血刀双刃

【游戏功能】 技能为什么总是不扣自己的血?血刃偏要反着来:开着血刃的每一刀先扣自己二血、命中回三血——净赚一但要打得中,空刀…

2026-10-01 10:00 996 技术组
进阶实战游戏功能

破军旗:旗立三秒圈内加攻,旗倒攻散

【游戏功能】 bn.t = bn.t - dt ——一行旗面倒计时的代码,撑起了破军旗全部的紧迫感:旗立三秒、圈内加攻三成,…

2026-10-01 10:00 996 技术组
进阶实战游戏功能

淬毒刃:淬毒三刀叠一层,一层毒过一秒六

【游戏功能】 淬毒为什么要一毒到底?淬毒刃偏要一层一层叠:一刀淬一层毒、毒层一秒六地烂,六层封顶之后一刀下去毒伤三十六——叠…

2026-10-01 10:00 996 技术组