Lua Academy · 课时

避免内存泄漏

了解 Lua 中常见的泄漏模式及预防策略。

第 4 / 4 课13 个步骤

避免内存泄漏 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

Lua 中的内存泄漏是什么?

当某个引用阻止 GC 回收对象,而程序实际上已经不再需要这些对象时,它们会不断积累在内存中,这就发生了内存泄漏。

常见泄漏:全局累积

将对象存储在全局表中却从不移除,是一种典型的泄漏。全局表始终是 GC 根。

local cache = {}  -- global-like upvalue
function storeResult(key, val)
  cache[key] = val  -- never evicted!
end

修复:有界缓存

限制缓存大小,并使用 LRU 策略或简单的大小上限淘汰旧条目。

local MAX = 100
local function boundedStore(cache, key, val)
  if #cache >= MAX then
    table.remove(cache, 1)  -- evict oldest
  end
  cache[key] = val
end

常见泄漏:事件监听器

将闭包注册为事件监听器却从不注销,会使闭包及其上值一直存活。

local listeners = {}
function on(event, fn)
  listeners[event] = listeners[event] or {}
  listeners[event][#listeners[event]+1] = fn
end
-- Always provide off() to deregister!

修复:弱监听器表

将监听器存储在弱值表中。这样,如果订阅者对象被回收,其监听器也会自动移除。

local listeners = setmetatable({}, {__mode = "v"})

常见泄漏:捕获大型表的闭包

捕获大型表的闭包会在自身存活期间一直保持该表存活,即使实际只需要表中的一小部分内容。

local bigData = {-- 100MB of data --}
local fn = function()
  return bigData[1]  -- bigData stays alive!
end

修复:提取所需值

在创建闭包之前只提取所需的值,这样大型表就可以被回收。

local needed = bigData[1]
bigData = nil  -- allow collection
local fn = function() return needed end

协程泄漏

已挂起的协程仍然存活,并持有所有局部变量。已结束的协程(状态为 "dead")可以被回收。请不要丢失对已挂起协程的跟踪。

字符串累积

在循环中使用 .. 拼接字符串会创建许多中间字符串。请使用 table.concat 高效地构建大型字符串。

local parts = {}
for i = 1, 1000 do parts[i] = tostring(i) end
local result = table.concat(parts, ",")

调试泄漏

在操作前后使用 collectgarbage("count") 测量内存增长。记录可疑的增长,以缩小泄漏来源的范围。

local before = collectgarbage("count")
-- ... run operation ...
collectgarbage()
local after = collectgarbage("count")
print(("Delta: %.1f KB"):format(after - before))

性能分析工具

诸如 luamemprof 之类的工具,以及自定义的 debug.sethook 分配计数器,可以跟踪哪些代码路径分配了最多内存。

内存泄漏问题

哪种模式最有可能导致内存泄漏?

回顾:避免内存泄漏

Lua 中的泄漏来自无界缓存、未注销的监听器、捕获大型表的闭包,以及被遗忘的已挂起协程。请使用弱表、有界缓存和 collectgarbage("count") 来检测并防止泄漏。

免费开始

用 AI 导师学习 Lua — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
40
课程
159

常见问题解答

「避免内存泄漏」课时是免费的吗?

是的 — 「避免内存泄漏」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「避免内存泄漏」这节课中我会学到什么?

了解 Lua 中常见的泄漏模式及预防策略。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「避免内存泄漏」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Lua 垃圾回收基础
  2. 弱键和弱值
  3. 使用 __gc 执行终结操作
  4. 避免内存泄漏
← 返回 Lua Academy