【30天Lua重拾笔记31】进阶议题: 记忆体回收&弱表

TL;DR:
不要去修改预设值,除非你知道在做什麽

Lua会自己做记忆体回收,绝大多数时候不必为记忆体分配、管理而操心,而且通常它做的很好。但如果真的因为记忆体回收而影响到程序效率的执行,且你确定你有足够的记忆体,你可以暂停让Lua执行记忆体回收的操作:

停止收集记忆体垃圾

collectgarbage("stop")
collectgarbage("isrunning") --> false

或者,如果你是嵌入在C,可能会更倾向使用:

lua_gc(L, LUA_GCSTOP)

收集记忆体垃圾

如果要恢复,也只要:

collectgarbage("restart")
collectgarbage("isrunning") --> true

或是

lua_gc(L, LUA_GCRESTART)

记忆体收集策略

如果你很了解不同种的记忆体收集策略的优劣,Lua提供以下记忆体收集策略:

  • "collect"
    预设模式
  • "stop"
    除了手动触发以外,不执行记忆体回收。
  • "step"
  • "incremental"
  • "generational"

弱表

metatable有一个选项是__mode,可以使表变成是弱表,他有三个值 -- "k""v""kv"k就是key,也就是如果表的索引值是可以被回收,而且被回收了,这个栏位也就被回收了。v对应的是value,也就是如果表的值是可以被回收,而且被回收了,这个栏位也就被回收了。kv只要索引值或值其一被回收了,就不在保留该栏位。我们直接拿kv来试试:

collectgarbage("restart") -- 开始自动记忆体回收

weak_table = {}
setmetatable(weak_table, {__mode = "kv"})

key = {}
value = {}

weak_table[key] = 1
weak_table[10] = value

for k, v in pairs(weak_table) do
  print(k, v)  -- {[key] = 1, [10] = value}
end

key = nil
value = nil    -- 不保留(删除) key, value

collectgarbage()  -- 执行记忆体回收

for k, v in pairs(weak_table) do
  print(k, v)  -- nothing
end

意外吗?旅途还在继续,在听我罗唆几天XD。
本文同步发表於个人网站


<<:  28. Vuex State

>>:  小学生学程序设计 Day 29:「同学们,按照身高排好! 实作篇」

[访谈] APCS x 资讯科学班 tom1484

最後一位邀请到来自附中资讯科学班的 Tom 来分享~ 影片连结:https://youtu.be/b...

Python - Python SimpleHTTPServerWithUpload 参考笔记

Python - Python SimpleHTTPServerWithUpload 参考笔记 参考...

【踩坑】按钮闪阿闪,gradient 在 hover 时闪烁

某天在闲逛网站,美其名观察各种生态,实则打混摸鱼的时候 发现按钮在 hover 过渡时出现闪烁的状况...

Angular 如何取得 API 资料

既然昨天已经说了 http post 这件事,那今天就来说说 http get 这部份吧! 今天的资...

Day27 深入解析Elasticsearch Query DSL Range query

Hello大家, 真的把今年的国定假日都过完了... 有点哀伤! 下次的连续假期是跨年了, 让我们一...